(注意)触ると言ってもバイナリエディタで触るとかではありません!
まずこういうクラスがあります。
// Hoge.java class Hoge { static final String foo = "foo"; static String bar = "bar"; static final Object baz = "baz"; }
そして、これらのフィールドを使うクラスがあります。
// Fuga.java public class Fuga { public static void main(String[] args) { System.out.println(Hoge.foo); System.out.println(Hoge.baz); System.out.println(Hoge.bar); } }
そのままコンパイルします。
Airof:temp irof$ ls Fuga.java Hoge.java Airof:temp irof$ javac * Airof:temp irof$ ls Fuga.class Fuga.java Hoge.class Hoge.java
実行します。
Airof:temp irof$ java Fuga foo baz bar
普通ですね。
class Hoge { static final String foo = "FOOFOO"; static String bar = "BARBAR"; static final Object baz = "BAZBAZ"; }
Airof:temp irof$ javac Hoge.java
そんで実行。
Airof:temp irof$ java Fuga foo BAZBAZ BARBAR
知ってれば予想通りですかね。知らなければなんぞこれになるかもしれません。
わからない人は Fuga の javap すれば何となくわかるかも。
Compiled from "Fuga.java"
public class Fuga {
public Fuga();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String foo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: getstatic #5 // Field Hoge.baz:Ljava/lang/Object;
14: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
20: getstatic #7 // Field Hoge.bar:Ljava/lang/String;
23: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
26: return
}とりあえず、コンパイル後のclassファイルたちを触っちゃいけないです。通常はビルドツール使ってまとめてやるだろうから大丈夫なんだろうけども、まとめてコンパイルして、まとめてjarに入れるとかするべきです。
たまに特定のclassファイルだけ差し替えたり、選択してjar作ったりしてるところもあったりします。そう言うところではたまに ClassNotFoundException が出たりします。
例えば、上記の例で Hoge.class を削除して Fuga を実行すると出ます。
Airof:temp irof$ java Fuga foo Exception in thread "main" java.lang.NoClassDefFoundError: Hoge at Fuga.main(Fuga.java:4) Caused by: java.lang.ClassNotFoundException: Hoge at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 1 more
foo は出力されるんですよね。こんなトラブルの調査結果が「Hoge.foo は使えるのに Hoge.baz は使えない。原因不明。」とかになったりする。それも困った話ですけど、そもそもclassファイルを直接触らなきゃ起こらない話で。
素直にビルドツールを使えば良い話なんですけども。
冗談みたいに聞こえる実際の話だけど、これを本当に冗談にするのが自分たちのやらなきゃいけないことです。