Can I have macros in Java source files

后端 未结 8 2354
情话喂你
情话喂你 2020-11-28 03:15

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

相关标签:
8条回答
  • 2020-11-28 03:53

    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();
    
    0 讨论(0)
  • 2020-11-28 03:57

    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!

    0 讨论(0)
  • 2020-11-28 04:08

    You can do this, for example, with Java Primitive Specializations Generator:

    /* define READINT //
    new Scanner(System.in).nextInt();
    // enddefine */
    
    ...
    
    int a = /* READINT */0/**/;
    
    0 讨论(0)
  • 2020-11-28 04:13

    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();
     }
    
    0 讨论(0)
  • 2020-11-28 04:13

    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.

    0 讨论(0)
  • 2020-11-28 04:14

    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.

    0 讨论(0)
提交回复
热议问题