!!!ECJ (Eclipse Compiler for Java) {{category Eclipse,Java,nolink}}Eclipse (の JDT(Java Development Tools)) には、独自の Java コンパイラ ECJ (Eclipse Compiler for Java) があり、Eclipse での Java のコンパイルは ECJ で行われます。 !!!ECJ (Eclipse Compiler for Java) は面倒見が良すぎ… Eclipse (の JDT(Java Development Tools)) には、 独自コンパイラ ECJ (Eclipse Compiler for Java) があり Eclipse での Java のコンパイルは ECJ で行われます。 このECJの面倒見がよすぎて、JDK付属のコンパイラ javac で コンパイルをしたらエラーになって怒られるのがあります。 確認したのは、JDK 1.6.0_20、Eclipse SDK 3.5.0 ※Eclipse Project SDK Version: 3.5.0.v20090423、Eclipse Java Development Tools Version: 3.5.0.v20090527 !!■BOM付きUTF-8のjavaソースファイル UTF-8の規格上は、BOMが付いていてもOK。 ただ、javac は「Hoge.java:1: \65279 は不正な文字です。」とエラーになる。 Eclipse では、問題なくコンパイルできる。 さらに困ったことに、Eclipse 上でプロパティでエンコードは判断できるが BOM付きかの判断が出来ない。あり/なしで保存も出来ない。 !!■アノテーションでの各要素の値で配列の最後にカンマ 通常の配列の場合は、最後にカンマがあっても無視される。  String str[] = { "aa", "bb", "cc", }; 言語仕様でもそう定義されている。 "" A trailing comma may appear after the last expression in an "" array initializer and is ignored. "" "" The Java Language Specification, Third Edition - 10.6 Array Initializers "" http://java.sun.com/docs/books/jls/third_edition/html/arrays.html しかし、アノテーション(の要素の値)の場合、 javac では「Hoge.java:1: 式の開始が不正です。」とエラーになる。  @XmlType(propOrder = { "aa", "bb", "cc", })  public class Hoge { ...... } # 配列の初期化なんだから、通常の場合と同様に最後のカンマは、無視されてよさそうなんだけど…。 !!■代入演算子での Integer 変数への Double 変数の加算 次のような代入演算子の計算が、ECJ ではエラーとならない。  Integer i = 1;  Double d = 2.0D;  i += d; javac の場合は次のようなエラーになる。  Hoge.java:12: 変換できない型  検出値 : double  期待値 : java.lang.Integer   i += d; ^ "" A compound assignment expression of the form E1 op= E2 is equivalent "" to E1 = (T)( (E1) op (E2) ), where T is the type of E1, except that "" E1 is evaluated only once. "" "" The Java Language Specification, Third Edition - 15.26.2 Compound Assignment Operators "" http://java.sun.com/docs/books/jls/third_edition/html/expressions.html とあるので、「i += d;」は「i = (Integer) ( (i) + (d) );」の様に 展開されることになる。この場合、ECJ でも javac でもエラーとなる。 ECJ でビルドしたクラスをデコンパイルすると、 「i = Integer.valueOf( (int)( (double)i.intValue() + d.doubleValue() ) );」 となっている。 # でも、そもそも double の値を Integer (int) 変数にセットするのって危険な気が…。 !!■ジェネリックパラメータ 次のような generic を使ったソースの場合、 public T getValue(String key) { return getValueSub(key); } public T getValueSub(String key) { return null; } javac の場合は次のようなエラーになる。 Hoge.java:13: 型パラメータ T を判別できません; 型変数 T (上限 T,java.lang.Object) の固有の最大インスタンスが存在しません。 return getValueSub(key); ^ 「return this.getValueSub(key);」の様に型を指定すればエラーなく通る。