Question

I am a fan of static metaprogramming in C++. I know Java now has generics. Does this mean that static metaprogramming (i.e., compile-time program execution) is possible in Java? If so, can anyone recommend any good resources where one can learn more about it?

Was it helpful?

Solution

No, this is not possible. Generics are not as powerful as templates. For instance, a template argument can be a user-defined type, a primitive type, or a value; but a generic template argument can only be Object or a subtype thereof.

Edit: This is an old answer; since 2011 we have Java 7, which has Annotations that can be used for such trickery.

OTHER TIPS

Take a look at Clojure. It's a LISP with Macros (meta-programming) that runs on the JVM and is very interoperable with Java.

What do you exactly mean by "static metaprogramming"? Yes, C++ template metaprogramming is impossible in Java, but it offers other methods, much more powerful than those from C++:

  • reflection
  • aspect-oriented programming (@AspectJ)
  • bytecode manipulation (Javassist, ObjectWeb ASM, Java agents)
  • code generation (Annotation Processing Tool, template engines like Velocity)
  • Abstract Syntax Tree manipulations (APIs provided by popular IDEs)
  • possibility to run Java compiler and use compiled code even at runtime

There's no best method: each of those methods has its strengths and weaknesses. Due to flexibility of JVM, all of those methods in Java can be used both at compilation time and runtime.

No. Even more, generic types are erased to their upper bound by the compiler, so you cannot create a new instance of a generic type T at runtime.

The best way to do metaprogamming in Java is to circumvent the type erasure and hand in the Class<T> object of your type T. Still, this is only a hack.

No, generics in Java is purely a way to avoid casting of Object.

If you need powerful compile-time logic for Java, one way to do that is with some kind of code generation. Since, as other posters have pointed out, the Java language doesn't provide any features suitable for doing compile-time logic, this may be your best option (iff you really do have a need for compile-time logic). Once you have exhausted the other possibilities and you are sure you want to do code-generation, you might be interested in my open source project Rjava, available at:

http://www.github.com/blak3mill3r

It is a Java code generation library written in Ruby, which I wrote in order to generate Google Web Toolkit interfaces for Ruby on Rails applications automatically. It has proved quite handy for that.

As a warning, it can be very difficult to debug Rjava code, Rjava doesn't do much checking, it just assumes you know what you're doing. That's pretty much the state of static metaprogramming anyway. I'd say it's significantly easier to debug than anything non-trivial done with C++ TMP, and it is possible to use it for the same kinds of things.

Anyway, if you were considering writing a program which outputs Java source code, stop right now and check out Rjava. It might not do what you want yet, but it's MIT licensed, so feel free to improve it, deep fry it, or sell it to your grandma. I'd be glad to have other devs who are experienced with generic programming to comment on the design.

Lombok offers a weak form of compile time metaprogramming. However, the technique they use is completely general.

See Java code transform at compile time for a related discussion

I'm not sure I understand the advantage of static meta-programming.

In Java, you can reflect to find information about your classes and do all the things meta-programming would do, you just get to do them inside your code without adding new syntax and different ways of thinking. Annotations are also able to do certain meta-programming tasks in a more structured way.

I could be wrong about this, I'm seriously considering opening a question on it because I'm not sure I get it. It seems like static meta-programming is a neat hack that gets around the fact that some languages don't keep a lot of compile-time information available at run-time (one of the strong points of Java and of dynamic languages).

If anyone could reply with a link to an example where meta-programming offers a more understandable, readable or otherwise better solution than reflection would, I'd appreciate the effort.

The Manifold project offers type-safe static metaprogramming for Java. You can use it to build types dynamically at compile-time as Javac resolves type names. The JSON Schema demo demonstrates static metaprogramming in terms of dynamic, compile-time type projection (no code generation build steps).

Additionally you can use Manifold to add new features. Check out Structural Typing, Method Extensions, and Type-safe Reflection. .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top