So-net無料ブログ作成

+= 複合代入演算子と文字列 [Java]


Java Puzzlers 罠、落とし穴、コーナーケース

Java Puzzlers 罠、落とし穴、コーナーケース

  • 作者: ジョシュア・ブロック
  • 出版社/メーカー: ピアソン・エデュケーション
  • 発売日: 2005/11/14
  • メディア: 大型本



土曜日にJoshua Blochと話をした際に、『Java言語仕様第3版』での言語仕様の変更により、『Java Puzzlers』のパズルを一部書き直す必要があるということでした。それで、調べてみました。

『Java言語仕様第2版』までは、以下のコードは文法エラーでした。
Object o = new Object(); o += "test";

なぜならば、15.26.2節「複合代入演算子」には、次の定義が記述されていたからです。
左手側オペランドがString型であれば右手側オペランドはどのような型でも構わない +=をのどいて、すべての複合代入演算子では双方のオペランドがプリミティブ型でなけれればならない。

E1 op= E2形式の複合代入式では、E1が一度だけ評価される点を除き、E1型をTとしたE1 = (T)((E1) op (E2))と等価なものになる。暗黙のうちに行われるT型へのキャストは、好投変換(§5.1.1)、あるいはプリミティブ型のナローイング変換(§5.1.3)となることに注意されたい。

しかし、リリース1.5でオートボクシングが導入された際に、この記述は『Java言語仕様第3版』では次の記述だけとなりました。
E1 op= E2形式の複合代入式では、E1が一度だけ評価される点を除き、E1型をTとしたE1 = (T)((E1) op (E2))と等価なものになる。

つまり、o += "test";は、次のように解釈される訳です。
o = (Object)((o) + ("test"));

このコードは文法的には正しいですから、o += "test";も正しいことになります。しかし、最新のJava 6 Update 10のコンパイラでも、o += "test";は、コンパイルエラーとなります。

Bug Databaseを見ると、これは言語仕様のバグではなく、コンパイラのバグとして認識されているようで、Java 7で修正されるようです。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4741726

ということで、「パズル10 トウィードルディ(Tweedledee)」 は、Java 7がリリースされた時には、書き直す必要があることになります。



スポンサーリンク





nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました