Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is static metaprogramming possible in Java?

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?

like image 802
jwfearn Avatar asked Sep 21 '08 22:09

jwfearn


People also ask

What is static metaprogramming?

Static metaprogramming means doing that work at compile-time, and typically modifying or adding to the program based on that work. Static Metaprogramming would allow developers to enhance the features of a class, a method, or a type by adding any kind of code at static time.

Does Java support meta programming?

Metaprogramming is the secret behind the success of many Java frameworks such as Spring and Struts 2, and constitutes the backbone of many of the most fundamental APIs across the Java EE technology stack. More importantly, you can use metaprograming for improving your apps and app testing.

Is Java reflection metaprogramming?

No. Rather, reflection provides facilities that are a subset of what metaprogramming can do. Metaprogramming is "programs which write programs".

Are generics metaprogramming?

Again, in general, a metaprogram is a program that yields another program, whereas generic programming is about parametrized(usually with other types) types(including functions) .


3 Answers

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.

like image 151
Thomas Avatar answered Oct 24 '22 10:10

Thomas


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

like image 31
Lou Franco Avatar answered Oct 24 '22 11:10

Lou Franco


The short answer

This question is nearly more than 10 years old, but I am still missing one answer to this. And this is: yes, but not because of generics and note quite the same as C++.

As of Java 6, we have the pluggable annotation processing api. Static metaprogramming is (as you already stated in your question)

compile-time program execution

If you know about metaprogramming, then you also know that this is not really true, but for the sake of simplicity, we will use this. Please look here if you want to learn more about metaprogramming in general.

The pluggable annotation processing api is called by the compiler, right after the .java files are read but before the compiler writes the byte-code to the .class files. (I had one source for this, but i cannot find it anymore.. maybe someone can help me out here?).

It allows you, to do logic at compile time with pure java-code. However, the world you are coding in is quite different. Not specifically bad or anything, just different. The classes you are analyzing do not yet exist and you are working on meta data of the classes. But the compiler is run in a JVM, which means you can also create classes and program normally. But furthermore, you can analyze generics, because our annotation processor is called before type erasure.

The main gist about static metaprogramming in java is, that you provide meta-data (in form of annotations) and the processor will be able to find all annotated classes to process them. On (more easy) example can be found on Baeldung, where an easy example is formed. In my opinion, this is quite a good source for getting started. If you understand this, try to google yourself. There are multiple good sources out there, to much to list here. Also take a look at Google AutoService, which utilizes an annotation processor, to take away your hassle of creating and maintaining the service files. If you want to create classes, i recommend looking at JavaPoet.

Sadly though, this API does not allow us, to manipulate source code. But if you really want to, you should take a look at Project Lombok. They do it, but it is not supported.


Why is this important (Further reading for the interested ones among you)

TL;DR: It is quite baffling to me, why we don't use static metaprogramming as much as dynamic, because it has many many advantages.

Most developers see "Dynamic and Static" and immediately jump to the conclusion that dynamic is better. Nothing wrong with that, static has a lot of negative connotations for developers. But in this case (and specifically for java) this is the exact other way around.

Dynamic metaprogramming requires reflections, which has some major drawbacks. There are quite a lot of them. In short: Performance, Security, and Design.

Static metaprogramming (i.e. Annotation Processing) allows us to intersect the compiler, which already does most of the things we try to accomplish with reflections. We can also create classes in this process, which are again passed to the annotation processors. You then can (for example) generate classes, which do what normally had to be done using reflections. Further more, we can implement a "fail fast" system, because we can inform the compiler about errors, warnings and such.

To conclude and compare as much as possible: let us imagine Spring. Spring tries to find all Component annotated classes at runtime (which we could simplify by using service files at compile time), then generates certain proxy classes (which we already could have done at compile time) and resolves bean dependencies (which, again, we already could have done at compile time). Jake Whartons talk about Dagger2, in which he explains why they switched to static metaprogramming. I still don't understand why the big players like Spring don't use it.

This post is to short to fully explain those differences and why static would be more powerful. If you want, i am currently working on a presentation for this. If you are interested and speak German (sorry about that), you can have a look at my website. There you find a presentation, which tries to explain the differences in 45 minutes. Only the slides though.

like image 13
Thorben Kuck Avatar answered Oct 24 '22 10:10

Thorben Kuck