2008-09-21 14 views
33

Soy fan de static metaprogramming in C++. Sé que Java ahora tiene genéricos. ¿Esto significa que la metaprogramación estática (es decir, la ejecución del programa en tiempo de compilación) es posible en Java? Si es así, ¿alguien puede recomendar algún buen recurso donde se pueda obtener más información al respecto?¿Es posible la metaprogramación estática en Java?

+0

Por curiosidad: Más allá del desafío técnico, ¿cuáles son los beneficios prácticos de metaprogramming estática? – Uri

+1

@Uri: mover tantas fuentes de trabajo y error al tiempo de compilación como sea posible: generación de código, optimización y polimorfismo estático serían algunas palabras clave. –

Respuesta

22

No, esto no es posible. Los genéricos no son tan poderosos como las plantillas. Por ejemplo, un argumento de plantilla puede ser un tipo definido por el usuario, un tipo primitivo o un valor; pero un argumento de plantilla genérico solo puede ser Object o un subtipo del mismo.

Editar: Esta es una respuesta anterior; desde 2011 tenemos Java 7, que tiene Annotations that can be used for such trickery.

+2

+1: ¡Excelente respuesta! – Partial

+3

Sin embargo, la reflexión es más poderosa que las plantillas: ¿por qué usaría la herramienta incorrecta (genéricos) para el trabajo? –

+10

Una palabra: tipo de seguridad. (Zero ... one ... see? One word.) – Thomas

2

No, los genéricos en Java son puramente una manera de evitar el lanzamiento de Object.

+0

No es técnicamente cierto, ya que algunos genéricos están disponibles en tiempo de ejecución. por ejemplo, Gadget de Gafter: http://gafter.blogspot.ca/2006/12/super-type-tokens.html – btiernay

3

No, aún más, los tipos genéricos se borran a su límite superior por el compilador, por lo que no puede crear una nueva instancia de un tipo genérico T en tiempo de ejecución.

La mejor manera de metaprogramar en Java es eludir el borrado de tipo y la mano en el objeto Class<T> de su tipo T. Sin embargo, esto es solo un truco.

12

Eche un vistazo a Clojure. Es un LISP con Macros (meta-programación) que se ejecuta en la JVM y es muy interoperable con Java.

+2

no se puede conseguir mucho más que la meta Lisp – gtrak

0

No estoy seguro de entender la ventaja de la meta-programación estática.

En Java, puede reflexionar para encontrar información sobre sus clases y hacer todo lo que haría la meta-programación, solo tiene que hacerlas dentro de su código sin agregar nueva sintaxis y diferentes formas de pensar. Las anotaciones también pueden realizar ciertas tareas de metaprogramación de una manera más estructurada.

Podría estar equivocado al respecto, estoy considerando seriamente abrir una pregunta porque no estoy seguro de entenderlo. Parece que la meta-programación estática es un truco perfecto que evita el hecho de que algunos lenguajes no mantienen una gran cantidad de información en tiempo de compilación disponible en tiempo de ejecución (uno de los puntos fuertes de Java y de los lenguajes dinámicos).

Si alguien pudiera responder con un enlace a un ejemplo donde la meta-programación ofrece una solución más comprensible, legible o mejor que la reflexión, agradecería el esfuerzo.

+0

Aquí es una tarea metaprogramming que es simplemente imposible desde el interior de C++: reestructurar la arquitectura. Hay dos documentos se pueden leer sobre el tema: Akers, Baxter, Mehlich, Ellis, Luecke, "Estudio de caso: Re-ingeniería de componentes C++ Modelos Via automática de programas de transformación", Información y Tecnología de Software 49 (3): 275-291 2007 . disponible a partir de editor, y describe el resultado final y ... –

+0

.... y (los mismos autores) "re-ingeniería de componentes C++ Modelos Via automática de programas de transformación", disponible en http://www.semanticdesigns.com/Company/ Publicaciones. Esto describe el trabajo en un estado incompleto pero tiene mucho del mismo sabor. –

+0

Me refería a una ventaja de meta-programación sobre una tecnología más activa como la reflexión. Reconozco que C++ se limita a la actividad en tiempo de compilación y, por lo tanto, puede tener que pasar por aros para hacer cosas que los lenguajes dinámicos o de VM podrían hacer en tiempo de ejecución, pero ¿por qué querría un hack como plantillas cuando tiene una verdadera reflexión? –

2

Si necesita poderosa lógica de tiempo de compilación para Java, una forma de hacerlo es con algún tipo de generación de código. Dado que, como otros críticos han señalado, el lenguaje Java no proporciona ningún características convenientes para hacer en tiempo de compilación lógica, ésta puede ser su mejor opción (si y sólo si usted realmente tiene una necesidad de la lógica de tiempo de compilación). Una vez que haya agotado todas las otras posibilidades y que son Seguro que quiere hacer de generación de código, que podría estar interesado en mi proyecto de código abierto Rjava, disponible en:

http://www.github.com/blak3mill3r

Es una generación de código Java biblioteca escrita en Ruby, que escribí para generar automáticamente las interfaces de Google Web Toolkit para las aplicaciones de Ruby on Rails. Ha resultado bastante útil para eso.

Como advertencia, que puede ser muy difícil de depurar código Rjava, Rjava no hace mucho de cheques, sólo se asume que sabes lo que estás haciendo.Eso es más o menos el estado de metaprogramación estática de todos modos. Diría que es mucho más fácil de depurar que cualquier cosa no trivial con C++ TMP, y es posible usarlo para el mismo tipo de cosas.

De todos modos, si estaba pensando en escribir un programa que emite el código fuente de Java, deténgase ahora y eche un vistazo a Rjava. Puede que aún no haga lo que usted desea, pero tiene licencia MIT, así que siéntase libre de mejorarlo, freírlo o vendérselo a su abuela. Me gustaría que otros desarrolladores con experiencia en programación genérica comenten sobre el diseño.

4

¿Qué quiere decir exactamente con "metaprogramación estática"? Sí, C++ metaprogramming plantilla es imposible en Java, pero ofrece otros métodos, mucho más potentes que los de C++:

  • reflexión
  • programación orientada a aspectos (@AspectJ)
  • la manipulación de código de bytes (Javassist, ObjectWeb ASM, agentes de Java)
  • generación de código (herramienta de procesamiento de anotación, motores de plantilla como la velocidad) manipulaciones
  • árbol de sintaxis abstracta (API proporcionadas por los entornos de desarrollo populares)
  • posibilidad para ejecutar el compilador de Java y usar el código compilado, incluso en tiempo de ejecución

No existe el mejor método: cada uno de esos métodos tiene sus fortalezas y debilidades. Debido a la flexibilidad de JVM, todos estos métodos en Java se pueden usar tanto en tiempo de compilación como en tiempo de ejecución.

Cuestiones relacionadas