Java Genericsが難しい(4)

3.ジェネリクスと可変長引数と継承

以下のコードをコンパイル,実行すると、実行時エラー(ClassCastException)になる。



class Plus {
  R apply(T... t) {
    return t[0] + t[1];
  }
}

class Client {
  public void main(String[] args) {
    Plus<Integer,Integer> p = new Plus<
Integer,Integer>();
    Integer result = p.apply(1,2);
       :
       :
  }
}


私はjad使ってイレイジャの処理を見ていたのですぐにわかったが、
ソースコードだけ見て原因を特定できる人はすごいと思う。
jadで逆コンパイルすると以下のコードになる。

class Plus {
  Object apply(Ojbect[] t) {
    return apply((Integer[]) t);
// <- Integer[]型キャスト時エラー
  }
  Integer apply(Integer[] t) {
    return t[0] + t[1];
  }

}
class Client {
  public void main(String[] args) {
    Plus p = new Plus
();
    Integer result =
      p.apply(new Object[] {1,2}); // <- Object[]型で渡される        :
       :
  }
}


イレイジャ処理で生成されたブリッジメソッドに対し、可変長引数の処理が
行われるためブリッジメソッド内部で無理やりキャストする処理でエラーになる。
ブリッジメソッド、可変長引数など自動生成されるコード内でのエラーのため
これははまると解決が大変なエラーだと思う。

ということで可変長引数とジェネリクスの組み合わせは良くない組み合わせ
だと思う。
 
 

コメント

このブログの人気の投稿

日食ツアーその後

NashornがOpenJDKのリポジトリに入ってたのでビルドしてみた

Javaのクロージャをいじってみた。(1)