NetBeans7上でJDK7を用いてEclipseと結果が異なっていたコンパイラの挙動を確認する
JDK7はこちらからダウンロードできる最新版(Build 141)を使用しました。なお、NetBeans7のリリースニュースで出ていた”JDK7デベロッパプレビュー版”というのはおそらくこちらのBuild 140ではないかと思いますので、若干バージョンが違います。
NetBeans実行に用いるJDKを変更するには、以前のエントリ
で記載しましたが、現在では日本語公式サイトにも方法が載っているようです。
NetBeansを起動しメニューから”ヘルプ”>”製品について”を選ぶと以下のような表示になりました。
製品バージョン: NetBeans IDE 7.0 (Build 201104080000)
Java: 1.7.0-ea; Java HotSpot(TM) 64-Bit Server VM 21.0-b11
システム: amd64 上で動作する Windows 7 バージョン 6.1; MS932; ja_JP (nb)
[追記: NetBeans7.0をJDK7eaで動作させると問題がいくつか出ました。ですのでこの設定で常用はしない方が良いでしょう。Java7を使用したいだけであれば上記の設定は不要です。]
また、プロジェクトをJava7でコンパイルするには、プロジェクトビューア(ウインドウ左上部にツリー表示されているやつですね)でプロジェクトを右クリックし”プロパティ”を選択するとプロジェクトプロパティーダイアログが開きますので”ソース”の”ソース/バイナリ形式”で”JDK7”を選択します。
[追記: 片貝さんのエントリにおいて図入りでより詳しく説明されています。]
さて何から試すか…取り敢えず私が昔エントリに書いたものを。
これはNetBeans7でも解消されていないですね…当初は6.9.1で修正予定、次に7で、とずれ込んでいったのですが、残念ながら今回も未修正のようです。続いてこちら。
よしよし、JDK7で正常に実行できました。…あれ?JDK6でもうまくいくぞ…?どうやらこれは6u18で修正されたようです(6548436:Incorrect inconvertible types error)。
気を取り直して、以降、普通の業務系Javaプログラマなら必ず一度は罠にはまるEclipseコンパイラ(ECJというそうです)とOracle JDK6で差異があった部分がどうなったかを試してみます。問題の詳細はこちらでまとめている方がいらっしゃいましたので、そのエントリを参照してください。
『BOM付きUTF-8のjavaソースファイル』
BOM付きのテキストファイルはおそらくNetBeans単体では作れないと思うので、サクラエディタで保存したものを読み込ませてみたところやっぱり駄目でした。”エラー: \65279は不正な文字です”というエラーがでます。なお、NetBeansのエディタではBOMが見えてますので手で削除できました。
『アノテーションでの各要素の値で配列の最後にカンマ』
JDK7でコンパイル通りました。
『代入演算子での Integer 変数への Double 変数の加算』
Bug Databaseでは見つけられませんでしたが、下のbugの関連先でしょうかね?
ちなみに、double型(及びDouble型)からInteger型への変換が暗黙的には行えない、というのが問題の本質で、DoubleからのアンボクシングとIntegerへのボクシングを行ってもらえるよう、それぞれ明示的に型キャストしてあげればJDK6コンパイラに受け入れられるみたいです。
1: Integer i = 1;
2: Double d = 2.0D;
3: i+=(int)(double)d;
確かにコンパイラがDoubleとint, doubleとIntegerの関係なんか知るか!って言いたい気持ちも分からなくはないですが、あんまりこんなコードは見たくないですね…
[追記: 元々の式は (int)+(double) だったのに対して上の式は (int)+(int) になっているので上の式は誤りですね。まあ、あくまでコンパイルを通すための手段の例示、ということで。]
JDK7では元のコードのままでコンパイルが通りました。これをJD-GUIでデコンパイルすると
Integer.valueOf((int)(localInteger.intValue() + localDouble.doubleValue()));
のような形になりました。Eclipseと一緒ですね。
『ジェネリックパラメータ』
最新のJDK6では修正されていました。6u22-revというバージョン表記が何を意味しているのか理解していないのですが、私のインストールしているJDKで確認したところ、6u20,6u21,6u22はNG、6u25はコンパイルOKでした。JDK7でももちろんOKです。
一番最初に記載したEnumの問題に次いでこれでよく引っかかってたのですが、そうか、JDK6を最新版にすれば大半は解消するんですね…
『拡張for文 (foreach文) のキャスト』
bugdatabaseと格闘する集中力が切れました…
JDK7では正常に実行終了します。JDK7でコンパイルしたものを先程と同じくJD-GUIで見てみると、
1: for (Number localNumber : localArrayList2) {
2: System.out.print(localNumber);
3: System.out.println();
4: }
あれ、拡張for文が展開されていないですね。仕方が無いのでjavap –v の出力結果をJDK6のものとJDK7のもので比べてみると、JDK6では
50: checkcast #11; //class java/lang/Double
となっているコメントが、JDK7では
50: checkcast #11 // class java/lang/Number
になっていました。
結論としては、Java7では目につくEclipseコンパイラとの動作差異は粗方無くなっていると見てよいのではないでしょうか。
最近のコメント