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

在我的程序中,我多次阅读整型表单控制台。 每一次,我需要input这一行。

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

我习惯于C / C ++,我想知道是否可以定义类似的东西

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

然后,在我的Java程序中的每一个地方,我可以读取表格控制台

 int a = new READINT; 

但是我阅读表单本书不支持macros。

有人请解释我为什么这样,我可以用其他方式来做这件事。

可以,但你不应该

不应该分开:

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

jar头部分:(*)

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

这是一个演示:

src/Test.java

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

cpp命令:

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

结果:

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

编译:

 $ javac preprocessed/Test.java 

更好的解决方法:

你可以用静态方法来编写自己的工具类:

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

而当你想使用它,你可以静态导入readInt方法:

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

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

最后,一个轶事

我自己曾经在Java代码上使用过CPP预处理方法! 我正在创build一门课程的编程任务。 我希望能够轻松地从参考解决scheme中提取代码框架。 所以我只用了一些#ifdef来过滤解决scheme的“秘密”部分。 这样我可以维护参考解决scheme,并轻松地重新生成代码框架。


这篇文章在这里被重写为一篇文章。


(*)由于我讨厌以“你不应该”的方式回答问题。 此外,一些未来的读者可能有充分的理由想要使用cpp结合Java源代码!

不,Java(语言)不支持任何types的macros。

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

 int nextInt() { return new Scanner(System.in).nextInt(); } ... int a = nextInt(); int b = nextInt(); 

但好多了:

 Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int b = scanner.nextInt(); 

快乐的编码。


征求意见:

静态方法可以被调用,而不需要一个对象来调用它们。 然而,在大多数情况下,一个已经在一个对象 。 考虑:

 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(); } } 

Java不支持macros。 IIRC,语言devise者认为macros和所产生的预备者是一个不必要和不受欢迎的并发症。

改用一个函数:

 public int readInt(Scanner inp) { return inp.nextint(); } 

别处:

 Scanner input=new Scanner(System.in); ... int a=readInt(input); 

还要注意,我创build一次扫描仪并重新使用它。

Java中没有macros观概念。 如果你做了这么多,每次安装一个新的Scanner是个不错的主意。 定义一个公共的静态Scanner然后每次重复使用它:

 public class YourClass { public static final Scanner SCANNER= new Scanner(System.in); ... } // Somewhere in your code YourClass.SCANNER.nextInt(); 

Java不支持macros,因为Java的devise者select不包含这个function。 更长的答案是,Java没有像C / C ++那样的预处理器,并且不能执行预处理器通常会这样做的function。 我将实现这一点的方式只是创build一个包装Scanner构造函数调用的包装类。 也许类似

 public static int readInt(){ return new Scanner(System.in).nextInt(); } 

或者,更好的是,

 public class ScannerWrapper{ private static Scanner instance = null; public static int readInt(){ if (instance == null){ instance = new Scanner(System.in); } return instance.nextInt(); } 

如果你想使用C风格的macros,那么有人写了一个预处理器http://www.slashdev.ca/javapp/我不知道它有多好。;

使用工具类和静态导入。

实用程序类:

 package my.utils; public class ScannerUtils { private ScannerUtils() {} public static int readInt() { return new Scanner(System.in).nextInt(); } } 

使用实用程序类:

 package my.examples; import static my.utils.ScannerUtils.*; class Example { void foo() { int i = readInt(); } } 

正如其他人所说,你应该caching你的扫描仪,但这是一个单独的话题。