Reputation: 3307
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.
Upvotes: 58
Views: 92295
Reputation: 421160
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
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 #ifdef
s to filter out the "secret" parts of the solution. That way I could maintain the reference solution, and easily regenerate the code skeleton.
(*) 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!
Upvotes: 177
Reputation: 51
Macros are text-level pre-processing tools that can be badly abused if not carefully designed. Example:
#define MULTIPLY( a, b ) ( a * b )
MULTIPLE(1+2,3+4) will have the result of (1+2*3+4)
Another example
#define SQUARE( a ) ((a) * (a))
int x = 5;
SQUARE(x++);
will increment x twice. ((x++) * (x++))
I think that Java language designers did not buy it for these reasons, because it is meant to be simple.
Upvotes: 0
Reputation: 15313
You can do this, for example, with Java Primitive Specializations Generator:
/* define READINT //
new Scanner(System.in).nextInt();
// enddefine */
...
int a = /* READINT */0/**/;
Upvotes: 0
Reputation: 3192
There is no macro concept in Java. If you're doing that a lot, it's a bad idea to instantiate a new Scanner
each time. Define a public static Scanner
then reuse it each time:
public class YourClass {
public static final Scanner SCANNER= new Scanner(System.in);
...
}
// Somewhere in your code
YourClass.SCANNER.nextInt();
Upvotes: 0
Reputation:
No. Java (the language) does not support macros of any sort.
However, certain constructs can be faked or wrapped. While the example is silly (why are you creating a new scanner each time!?!?!) the below shows how it can be achieved:
int nextInt() {
return new Scanner(System.in).nextInt();
}
...
int a = nextInt();
int b = nextInt();
But much better:
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
Happy coding.
For comment:
Static methods can be called without needing an object to invoke them upon. However, in most cases one is already in an object. Consider:
public class Foo {
static int nextIntStatic() {
return 13;
}
int nextInt() {
return 42;
}
void realMain () {
// okay to call, same as this.nextInt()
// and we are "in" the object
int ni = nextInt();
}
public static void main(String[] args) {
// okay to call, is a static method
int nis = nextIntStatic();
Foo f = new Foo();
f.realMain();
}
}
Upvotes: 14
Reputation: 10216
If you want to use C-Style macros then someone has written a pre-processor http://www.slashdev.ca/javapp/ I have no idea how good it is though.
Upvotes: 0
Reputation: 13374
Use a utility class and static import.
The utility class:
package my.utils;
public class ScannerUtils {
private ScannerUtils() {}
public static int readInt() {
return new Scanner(System.in).nextInt();
}
}
Using the utility class:
package my.examples;
import static my.utils.ScannerUtils.*;
class Example {
void foo() {
int i = readInt();
}
}
As others have said, you should probably cache your scanner, but that is a separate topic.
Upvotes: -1
Reputation: 35598
Java doesn't support macros simply because the designers of Java chose not to include that functionality. The longer answer is that Java doesn't have a preprocessor the way C/C++ does and cannot perform that functionality that the preprocessor normally would. The way I would implement this is simply create a wrapper class that wraps up the Scanner
constructor calls. Perhaps something like
public static int readInt(){
return new Scanner(System.in).nextInt();
}
Or, better yet,
public class ScannerWrapper{
private static Scanner instance = null;
public static int readInt(){
if (instance == null){
instance = new Scanner(System.in);
}
return instance.nextInt();
}
Upvotes: 3
Reputation: 64066
Java does not support macros. IIRC, the language designers felt that macros and the resultant preparser was an unnecessary and undesirable complication.
Use a function instead:
public int readInt(Scanner inp) {
return inp.nextint();
}
Elsewhere:
Scanner input=new Scanner(System.in);
...
int a=readInt(input);
Note also, that I create the scanner once and reuse it.
Upvotes: 1