In Java, macros are enhancements to JDK 7 compiler. It adds and supports compile time macros. Macros are Java classes that are instantiated and executed at compile-time. The macros take in a source file's parse tree and a ParserFactory that can be used to parse dynamically generated code.
The compiler is fully functional and includes a naïve proof of concept (macro). It takes a Java class in which fields are annotated in a special way and automatically produces getter and setter methods for those annotated fields.
These macros are used to implement a variety of additional languages but note that no modifications to the compiler. For example, non-Java languages like Python can be embedded directly in a Java source code and converted to a parse tree at a specific time.
In Java, macros can be included just by importing the macro class. The Java compiler scans the parsed source code for import statements and tries to instantiate the imported class. If the instantiated class implements the macro interface, it is made using a no-argument constructor and executed.
The above approach works well but it is inefficient. Here a change is suggested in which the use of volatile keyword is re-used for macro declarations. In order to execute a compile-time macro import volatile will use, just like import static for procedural programming.
It is still in suspense what will happen if macro throws an exception. Obviously, the compiler will generate a parse error for the class being altered by the macro but the compiler is not able to report a stack trace error which is a part of the parse error.
As macros exist solely at compile-time, I do not believe this language feature requires any changes to the reflection APIs.
I have rationales. Java is rapidly losing mindshare to dynamic languages like Ruby and Python. Adding compile-time macros can automate many repetitive development tasks while retaining the static safety of Java.
Can we create macros in Java, like CPP?
No, Java does not support macros. Besides this, we should pipe the source code through the C preprocessor. We should not use macros because preprocessor is considered bad practice. Hence, these have vanished in various modern languages.
In order to achieve the macro behavior, we can write a utility class with a static method. For example:
To keep invocations as concise as for a macro, we can statically import the method as follows: