我可以在 Java 源文件中有宏吗
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6525059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I have macros in Java source files
提问by Muthu Ganapathy Nathan
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
我习惯了 C/C++,我想知道我是否可以定义类似的东西
#define READINT Scanner(System.in).nextInt();
and then, in every place in my java program I can read form console as
然后,在我的 Java 程序的每个地方,我都可以将表单控制台读取为
int a = new READINT;
But I read form books Java does not support macros.
但我读过表格书 Java 不支持宏。
Someone please explain me why is it so, and can I do this in any other way.
有人请解释我为什么会这样,我可以用任何其他方式做到这一点。
采纳答案by aioobe
You canbut you shouldn't.
你可以,但你不应该。
The shouldn'tpart:
该不该部分:
You shouldn'tbecause using the pre-processor in that way is considered bad practiceto start with, and there are better and more Java-idiomatic ways to solve this use case.
您不应该这样做,因为以这种方式使用预处理器被认为是不好的做法,并且有更好、更多的 Java 惯用方法来解决这个用例。
The canpart: (*)
该CAN部分:(*)
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.
Java 本身不支持宏。另一方面,您可以像 C/C++ 编译链一样通过C 预处理器(简称 CPP)将源代码通过管道传输。
Here's a demo:
这是一个演示:
src/Test.java
:
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
命令:
$ 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:
当你想使用它时,你可以静态导入该readInt
方法:
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()
.)
(或做static import StdinUtil.STDIN;
并使用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.
我自己曾经在 Java 代码上使用过 CPP 预处理方法!我正在为一门课程创建一个编程作业。我希望能够轻松地从参考解决方案中提取代码框架。所以我只是用了几个#ifdef
s 来过滤掉解决方案的“秘密”部分。这样我就可以维护参考解决方案,并轻松地重新生成代码框架。
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!
(*) 因为我讨厌用“你不应该”来回答问题。此外,一些未来的读者可能有充分的理由想要将cpp
与 Java 源代码结合使用!
回答by Lawrence Dol
Java does not support macros. IIRC, the language designers felt that macros and the resultant preparser was an unnecessary and undesirable complication.
Java 不支持宏。IIRC,语言设计者认为宏和由此产生的预解析器是一种不必要且不受欢迎的复杂性。
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.
另请注意,我创建了一次扫描仪并重复使用它。
回答by Lawrence Dol
No. Java (the language) does not support macros of any sort.
不。Java(语言)不支持任何类型的宏。
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 muchbetter:
但很多更好:
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
Happy coding.
快乐编码。
For comment:
评论:
Static methodscan 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();
}
}
回答by Giann
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:
Java 中没有宏概念。如果你经常这样做,Scanner
每次都实例化一个新的是个坏主意。定义一个公共静态Scanner
然后每次重用它:
public class YourClass {
public static final Scanner SCANNER= new Scanner(System.in);
...
}
// Somewhere in your code
YourClass.SCANNER.nextInt();
回答by Chris Thompson
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
Java 不支持宏只是因为 Java 的设计者选择不包含该功能。更长的答案是 Java 没有像 C/C++ 那样的预处理器,并且不能执行预处理器通常会执行的功能。我实现它的方法是简单地创建一个包装类来包装Scanner
构造函数调用。也许像
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();
}
回答by Dilum Ranatunga
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.
正如其他人所说,您可能应该缓存您的扫描仪,但这是一个单独的主题。
回答by Greg Reynolds
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.
如果你想使用 C 风格的宏,那么有人写了一个预处理器http://www.slashdev.ca/javapp/我不知道它有多好。
回答by leventov
You can do this, for example, with Java Primitive Specializations Generator:
例如,您可以使用Java Primitive Specializations Generator执行此操作:
/* define READINT //
new Scanner(System.in).nextInt();
// enddefine */
...
int a = /* READINT */0/**/;