- ベストアンサー
コンパイラのバグ?それとも
- コンパイラのバグでしょうか。あるいは私の考えに間違いがあるのでしたら、指摘していただけるとありがたいです。
- 実行すると、nullと表示されてしまいます。つまり、コンパイル時に「t」の値が決まっていなければnullになってしまうようです。
- final String t = args[0];の部分をfinal String t = "Hello";のように書き換えると、Helloと表示されます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
私の環境 (java/javac 1.5.0_06) で試したら > java PossibleCompilerMalfunction Hello に対してちゃんと Hello と表示されましたよ。 質問者さんのコンパイラは最新のものですか? もし本当に「null」と表示されたのなら確かにバグだと思います。
その他の回答 (5)
- koki_m
- ベストアンサー率83% (45/54)
こんばんは。回答というより補足情報です。 まず、メソッド変数にfinalを付けた場合は「一度代入された値または参照を変更できない」というもので、使用方法は問題ないと思います。 私の環境でも試してみましたが、nullと表示されました。 javac -J-version = 1.4.2_08 java -version = 1.5.0_06 mainメソッド内にMyClassをすべて定義する場合はHelloが出力されます。 また、mainメソッドの最後で、mc.foo();とするとHelloが出力されます。 問題はMyClassのコンストラクタがfoo()メソッドを呼んでいる箇所のようです。 やはり、コンパイラのバグでしょうか?
お礼
回答ありがとうございます。 koki_mさんのコンパイラは、バージョン「1.4.2_08」のようですね。 最新のコンパイラに代えたら、うまく行くかもしれません。 UKYさんの回答に対する「お礼」を参照してください。
- tachiwa
- ベストアンサー率34% (25/73)
ANO4のtachiwaです。文頭に”コンパイルエラー”と書きましたが、”コンパイラのハグ”と訂正してください。
- tachiwa
- ベストアンサー率34% (25/73)
コンパイルエラーと断定は出来ませんが、UKYさんの主張が正しいと思います。次のように t="World"; を追加するとコンパイルエラーが出力されます。 public class PossibleCompilerMalfunction { public static void main(String[] args) { final String t = args[0]; t="World"; //追記 MyClass mc = new MyClass() { void foo() { System.out.println(t); } }; } static abstract class MyClass { MyClass() { foo(); } abstract void foo(); } } javacの結果 PossibleCompilerMalfunction.java:9: final 変数 t に値を代入することはできません 。 t="World"; ^ エラー 1 個
お礼
回答ありがとうございます。 UKYさんの回答に対するコメントに詳細を書きました。
finalとはまさに 「コンパイル時に値が決まっていなければならないもの」 です。 arg[0]はコンパイル時にはnullなので、コンパイラは間違っていません。
お礼
回答ありがとうございます。 しかし、final変数は、コンパイル時に値が決まっていなければならないとは限らないのでは? 「ブランクfinal変数」というのもありますし、 たとえば下のようなコードは、コンパイル時には値が決まっていません。 final String userName = System.getProperty("user.name"); また、配列argsの大きさは 実行時のコマンドライン引数によって決まるので、 args[0]はコンパイル時には決まっていないのではないでしょうか。
- driverII
- ベストアンサー率27% (248/913)
java の 変数の final 指定は定数ですから、 そうなりますね。 arg[0]は可変なのですから、final 指定しなければ、 OKでしょう。
お礼
回答ありがとうございます。 finalを指定しないローカル変数は 匿名クラス(あるいは無名クラス)からアクセスできないので やむをえずfinalを付けました。
お礼
回答ありがとうございます。 私の使ってるコンパイラは最新版です。 しかし、ひとつ謝らなくてはいけないことがあります。 古いJVMとの互換性を持たせるため、 (IEで動くアプレットを作ったりしているので) javacに常に「-target 1.1」というオプションをつける設定にしていたのを忘れてました。 つまり私の環境では、 javac SomeClass.java とタイプすると、下のように実行されるのです。 javac -source 1.2 -target 1.1 SomeClass.java オプションをつけないでコンパイルしたら、 (すなわち「-target 1.5」でコンパイルしたら) ちゃんと「Hello」と表示されました。 お騒がせしてすいません。 しかし、「-target 1.1」だと「null」になるのは やはりコンパイラのバグだと考えてよさそうでしょうか。
補足
ちょっと補足です。 >javacに常に「-target 1.1」というオプションをつける設定にしていたのを忘れてました。 このことを思い出したのは、 UKYさんの「コンパイラは最新のものですか? 」 という回答がきっかけだったことを書き加えておきます。