Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have macros in Java source files

Tags:

java

macros

In my program I'm reading integers form console many times. Every time, I need to type this line.

new Scanner(System.in).nextInt();  

I'm used to C/C++ and I'm wondering if I can define something like

#define READINT Scanner(System.in).nextInt();  

and then, in every place in my java program I can read form console as

int a = new READINT; 

But I read form books Java does not support macros.

Someone please explain me why is it so, and can I do this in any other way.

like image 560
Muthu Ganapathy Nathan Avatar asked Jun 29 '11 17:06

Muthu Ganapathy Nathan


People also ask

Can we use macros in Java?

No, Java does not support macros.

Can I use #define in Java?

Java doesn't have a general purpose define preprocessor directive. private static final int PROTEINS = 100; Such declarations would be inlined by the compilers (if the value is a compile-time constant).

Does Java have preprocessor?

Java doesn't have a preprocessor - so the simple answer is that you can't. This sort of thing is normally handled in Java using Dependency Injection - which is both more powerful and more flexible.

Are macros compiled?

Macros are pre-processed which means that all the macros would be processed before your program compiles. However, functions are not preprocessed but compiled. See the following example of Macro: C.


1 Answers

You can but you shouldn't.

The shouldn't part:

You shouldn't because using the pre-processor in that way is considered bad practice to start with, and there are better and more Java-idiomatic ways to solve this use case.


The can part: (*)

Java itself doesn't support macros. On the other hand, you could pipe the source code through the C pre processor (CPP for short) just like the C/C++ compile chain does.

Here's a demo:

src/Test.java:

#define READINT (new java.util.Scanner(System.in).nextInt())  class Test {     public static void main(String[] args) {         int i = READINT;     } } 

cpp command:

$ cpp -P src/Test.java preprocessed/Test.java 

Result:

class Test {     public static void main(String[] args) {         int i = (new java.util.Scanner(System.in).nextInt());     } } 

Compile:

$ javac preprocessed/Test.java 


A better workaround:

You can write your own utility class with a static method instead:

import java.util.Scanner; class StdinUtil {     public final static Scanner STDIN = new Scanner(System.in);     public static int readInt() {         return STDIN.nextInt();     } } 

And when you want to use it, you can statically import the readInt method:

import static StdinUtil.readInt;   class Test {     public static void main(String[] args) {         int i = readInt();     } } 

(or do static import StdinUtil.STDIN; and use STDIN.nextInt().)


And finally, an anecdote

I myself used the CPP preprocessing approach on Java code once! I was creating a programming assignment for a course. I wanted to be able to easily extract a code skeleton out of the reference solution. So I just used a few #ifdefs to filter out the "secret" parts of the solution. That way I could maintain the reference solution, and easily regenerate the code skeleton.


This post has been rewritten as an article here.


(*) Since I hate answering questions with "you shouldn't". Besides, some future reader may have good reasons for wanting to use the cpp in conjunction with Java sources!

like image 162
aioobe Avatar answered Oct 11 '22 06:10

aioobe