1. ホーム
  2. java

[解決済み] Javaソースファイルにマクロを入れることはできますか

2022-02-28 01:02:44

質問

私のプログラムでは、コンソールから何度も整数を読み取っています。毎回、この行をタイプする必要があります。

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

C/C++に慣れているので、以下のような定義ができないか?

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

そして、私のJavaプログラムのすべての場所で、私は次のようにフォームコンソールを読むことができます。

int a = new READINT;

しかし、私は、Javaがマクロをサポートしていないフォームの本を読んだ。

なぜそうなのか、また他の方法でこれを行うことができるのか、どなたか教えてください。

どのように解決するのですか?

あなたは 可能 しかし、あなたは いけない .

いけません の部分です。

あなたは はいけません。 なぜなら、そのような方法でプリプロセッサを使用すると はバッドプラクティスと考えられています。 このユースケースを解決するには、より良い、よりJava的な方法があります。


できる の部分になります。(*)

Java自身はマクロをサポートしていません。一方、ソースコードをパイプでつないで Cプリプロセッサ (略称:CPP)が、C/C++コンパイルチェーンが行うのと同じように。

以下はデモです。

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の前処理を使ったことがありますよ。ある講座でプログラミングの課題を作っていたときのことです。私は、参照解からコードのスケルトンを簡単に抽出できるようにしたかったのです。そこで、私はただいくつかの #ifdef を使用して、解答の「秘密」の部分をフィルタリングしています。そうすることで、参照解を維持しながら、簡単にコードスケルトンを再生成することができるのです。


この投稿は記事としてリライトされています こちら .


(*) 私は、質問に答えるときに、"you shouldn't" と答えるのが嫌いなので。それに、将来、読者が cpp をJavaのソースと組み合わせて使うことができます。