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程序的每个地方,我都可以读取form console as
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.
有人请解释为什么是这样,我可以用其他方法做吗?
134
You can but you shouldn't.
你可以,但你不应该。
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.
您不应该这样做,因为以这种方式使用预处理器被认为是不好的做法,并且有越来越多的java惯用方法来解决这个用例。
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
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()
.)
(或做静态导入StdinUtil.STDIN;和使用STDIN.nextInt())。
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预处理方法!我正在为一门课程创建一个编程任务。我希望能够轻松地从引用解决方案中提取代码框架。所以我只使用了一些#ifdefs来过滤解决方案的“秘密”部分。这样,我就可以维护引用解决方案,并轻松地重新生成代码骨架。
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源代码结合使用!
12
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 much better:
但更好的:
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
Happy coding.
快乐的编码。
For comment:
评论:
Static methods can 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();
}
}
1
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++那样的预处理器,并且不能执行预处理器通常会执行的功能。我实现它的方法是创建一个包装器类来包装扫描器构造函数调用。也许类似的
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
Java does not support macros. IIRC, the language designers felt that macros and the resultant preparser was an unnecessary and undesirable complication.
Java不支持宏。语言设计者认为宏和合成程序是一种不必要的、不受欢迎的复杂性。
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
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/我不知道它有多好。
0
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中没有宏概念。如果您经常这样做,那么每次实例化一个新的扫描器不是一个好主意。定义一个公共静态扫描器,然后每次重用它:
public class YourClass {
public static final Scanner SCANNER= new Scanner(System.in);
...
}
// Somewhere in your code
YourClass.SCANNER.nextInt();
-1
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.
正如其他人所说,您可能应该缓存扫描器,但这是一个单独的主题。