我可以在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你的扫描仪,但这是一个单独的话题。