回答編集履歴

2 ソースに対するコメント追加

MakotoMiyazaki

MakotoMiyazaki score 289

2016/03/02 14:59  投稿

そもそも、staticフィールドは該当クラスがロードされた際に
JVM上のヒープ領域内に1つ展開されるClassオブジェクト内に作成されます。
そのため、JVM起動から終了までstaticフィールドの箱は1つしかありません。
また、ヒープ内のClassオブジェクトとして展開されるため、インスタンス化しなくても利用することができます。
また、final修飾子は初期化時に設定した値を、そのJVM上では二度と変更しないためのもののため
これを外さなければ、値を更新することはできません。
なので、単純に考えるとご希望の動作は実現不可能です。
が、裏技を使えばできなくもなさそうです。
やり方は
1.Mainのhogeをcallして処理結果をreturnするクラスを用意する
2.testメソッドでそのクラスをコンパイルしたclassを実行する
3.処理結果を取得して検証する
という感じでいけるかもしれません。
こんな感じのソースでそれっぽいものが行けました。
以下のソースでそれっぽいものが行けました。
```java
//標準入力を促すMainクラス
public class Main {
   public static int hoge = get();
   private static int get() {
       try {
           return System.in.read();
       } catch (IOException e) {
           e.printStackTrace();
       }
       return 0;
   }
}
//そのMainクラスを実行するクラス
public class ExecMain {
   public static void main(String[] args) {
       System.out.println(Main.hoge);
   }
}
//ExecMainを呼び出すクラス(テストクラスになるはず)
public class Sample {
   public static void main(String[] args) {
       String test1Result = run("first");
       System.out.println("テスト1の処理結果は「" + test1Result + "」でした。");
       String test2Result = run("second");
       System.out.println("テスト2の処理結果は「" + test2Result + "」でした。");
   }
   public static String run(String input) {
       String result = "";
       try {
           // Runtime rt = Runtime.getRuntime();  
           ProcessBuilder pb = new ProcessBuilder();
           pb.command("java", "ExecMain");
           Process p = pb.start();
           PrintStream out = new PrintStream(p.getOutputStream());
           out.println(input);
           out.flush();
           out.close();
           p.waitFor();
           InputStream is = p.getInputStream();
           InputStreamReader isr = new InputStreamReader(is);
           BufferedReader br = new BufferedReader(isr);
           String tmp;
           while ((tmp = br.readLine()) != null) {
               result = tmp;
           }
           is.close();
           isr.close();
           br.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
       return result;
   }
}
```
```
(各種close処理が中途半端なのはご勘弁ください。。。)
1 サンプルソース追加

MakotoMiyazaki

MakotoMiyazaki score 289

2016/03/02 14:58  投稿

そもそも、staticフィールドは該当クラスがロードされた際に
JVM上のヒープ領域内に1つ展開されるClassオブジェクト内に作成されます。
そのため、JVM起動から終了までstaticフィールドの箱は1つしかありません。
また、ヒープ内のClassオブジェクトとして展開されるため、インスタンス化しなくても利用することができます。
また、final修飾子は初期化時に設定した値を、そのJVM上では二度と変更しないためのもののため
これを外さなければ、値を更新することはできません。
なので、単純に考えるとご希望の動作は実現不可能です。
が、裏技を使えばできなくもなさそうです。
やり方は
1.Mainのhogeをcallして処理結果をreturnするクラスを用意する
2.testメソッドでそのクラスをコンパイルしたclassを実行する
3.処理結果を取得して検証する
という感じでいけるかもしれません。
という感じでいけるかもしれません。
こんな感じのソースでそれっぽいものが行けました。
```java
//標準入力を促すMainクラス
public class Main {
   public static int hoge = get();
   private static int get() {
       try {
           return System.in.read();
       } catch (IOException e) {
           e.printStackTrace();
       }
       return 0;
   }
}
//そのMainクラスを実行するクラス
public class ExecMain {
   public static void main(String[] args) {
       System.out.println(Main.hoge);
   }
}
//ExecMainを呼び出すクラス(テストクラスになるはず)
public class Sample {
   public static void main(String[] args) {
       String test1Result = run("first");
       System.out.println("テスト1の処理結果は「" + test1Result + "」でした。");
       String test2Result = run("second");
       System.out.println("テスト2の処理結果は「" + test2Result + "」でした。");
   }
   public static String run(String input) {
       String result = "";
       try {
           // Runtime rt = Runtime.getRuntime();
           ProcessBuilder pb = new ProcessBuilder();
           pb.command("java", "ExecMain");
           Process p = pb.start();
           PrintStream out = new PrintStream(p.getOutputStream());
           out.println(input);
           out.flush();
           out.close();
           p.waitFor();
           InputStream is = p.getInputStream();
           InputStreamReader isr = new InputStreamReader(is);
           BufferedReader br = new BufferedReader(isr);
           String tmp;
           while ((tmp = br.readLine()) != null) {
               result = tmp;
           }
           is.close();
           isr.close();
           br.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
       return result;
   }
}
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る