我可以在Java源文件中使用宏吗?

Mut*_*han 47 java macros

在我的程序中,我多次在控制台中读取整数.每次,我都要输入这一行.

new Scanner(System.in).nextInt(); 
Run Code Online (Sandbox Code Playgroud)

我已经习惯了C/C++而且我想知道我是否可以定义类似的东西

#define READINT Scanner(System.in).nextInt(); 
Run Code Online (Sandbox Code Playgroud)

然后,在我的java程序的每个地方,我都可以读取表单控制台

int a = new READINT;
Run Code Online (Sandbox Code Playgroud)

但我读的表格书Java不支持宏.

有人请解释我为什么会这样,我可以用其他任何方式做到这一点.

aio*_*obe 148

可以,但你不应该.

不该部分:

不应该因为以这种方式使用预处理器被认为是不好的做法,并且有更好的和更多Java惯用的方法来解决这个用例.


CAN部分:(*)

Java本身不支持宏.另一方面,您可以通过C预处理器(简称CPP)管理源代码,就像C/C++编译链一样.

这是一个演示:

src/Test.java:

#define READINT (new java.util.Scanner(System.in).nextInt())

class Test {
    public static void main(String[] args) {
        int i = READINT;
    }
}
Run Code Online (Sandbox Code Playgroud)

cpp 命令:

$ cpp -P src/Test.java preprocessed/Test.java
Run Code Online (Sandbox Code Playgroud)

结果:

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

编译:

$ javac preprocessed/Test.java
Run Code Online (Sandbox Code Playgroud)


更好的解决方法:

您可以使用静态方法编写自己的实用程序类:

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

当您想要使用它时,您可以静态导入该readInt方法:

import static StdinUtil.readInt; 

class Test {
    public static void main(String[] args) {
        int i = readInt();
    }
}
Run Code Online (Sandbox Code Playgroud)

(或做static import StdinUtil.STDIN;和使用STDIN.nextInt().)


最后,一个轶事

我自己在Java代码上使用了CPP预处理方法一次!我正在为课程创建编程作业.我希望能够从参考解决方案中轻松提取代码框架.所以我只用了几个#ifdefs来过滤出解决方案的"秘密"部分.这样我就可以维护参考解决方案,并轻松地重新生成代码框架.


该帖子已被改写为一篇文章在这里.


(*)因为我讨厌用"你不应该"回答问题.此外,一些未来的读者可能有充分的理由想要cpp与Java源一起使用!

  • 纯粹的邪恶.尼斯. (45认同)
  • 如果你真的知道没有盒子,为什么要开箱即用?:) (2认同)

小智 12

不,Java(该语言)不支持任何类型的宏.

但是,某些构造可以伪造或包裹.虽然这个例子很愚蠢(为什么每次都要创建一个新的扫描仪!?!?!),下面显示了它是如何实现的:

int nextInt() {
   return new Scanner(System.in).nextInt(); 
}
...
int a = nextInt();
int b = nextInt();
Run Code Online (Sandbox Code Playgroud)

很多更好:

Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
Run Code Online (Sandbox Code Playgroud)

快乐的编码.


征求意见:

可以在不需要对象调用静态方法的情况下调用静态方法.但是,在大多数情况下,一个已经在一个对象中.考虑:

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您愿意,可以将方法设为静态。 (2认同)