型の不一致

Javaでは、プリミティブ型のクラスリテラルをそのラッパー型を利用して表現する。

int.class: Class

でも、プリミティブ型の配列はそのまま使える。

int.class: Class.class>

そこで、

static <C> Class<C> component(Class<C[]> array) {
    return null;
}
static <C> Class<C[]> array(Class<C> array) {
    return null;
}

という2つのメソッドを考えて、

  • component(int[].class);
  • array(int.class);

といった感じで呼び出す。

前者はint.class: Class> となり、型推論により

  • Class> << Class>
  • int << C
  • int << C

という感じでプリミティブ型を型変数Cに束縛しようとして失敗。コンパイルエラーとなる。

後者はint.class: Class となり、型推論により

  • Class << Class
  • Integer << C
  • C :> Integer

…と、結果的にC := Integerとなる。
戻り値にこの環境を適用すると、Class>になるので、component(int.class)とarray(int.class)は対称的であるような感じがするのに、前者はコンパイルエラー、後者はClass型の戻り値となる。

腑に落ちないのはなんだろ。


結局何が言いたかったかというと、java.lang.Classクラスのヘルパでcomponentとarrayがあれば、それなりに型安全に配列型使えたねということ。ただ、配列の具象化は要素型に未加工型とかくらいしか置けないから意味ないかも。