热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我能在Java源文件中有宏吗-CanIhavemacrosinJavasourcefiles

InmyprogramImreadingintegersformconsolemanytimes.Everytime,Ineedtotypethisline.在我

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.

有人请解释为什么是这样,我可以用其他方法做吗?

7 个解决方案

#1


134  

You can but you shouldn't.

你可以,但你不应该。

The shouldn't part:

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惯用方法来解决这个用例。


The can part: (*)

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().)

(或做静态导入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 #ifdefs 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源代码结合使用!

#2


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

#3


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

#4


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.

还要注意,我只创建一次扫描器,然后重用它。

#5


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/我不知道它有多好。

#6


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

#7


-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.

正如其他人所说,您可能应该缓存扫描器,但这是一个单独的主题。


推荐阅读
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • dotNet变量和数据类型详解,包括声明变量和五大类型
    本文详细介绍了dotNet编程中的变量和数据类型,包括声明变量和五大类型(int、double、decimal、string、char)。文章通过案例演示了变量的声明和赋值方法,并解释了每种数据类型的特点和使用场景。此外,还介绍了变量命名规则和一些特殊情况,如String与string的区别、float类型的使用等。阅读本文可以帮助读者更好地理解和应用dotNet编程中的变量和数据类型。 ... [详细]
author-avatar
极神bd韵
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有