ユーザ用ツール

サイト用ツール


java:covariant

文書の過去の版を表示しています。


共変(covariant)

共変の戻り値

Java5からメソッドをオーバーライドするとき、戻り値の型を変更することが可能になった。

共変戻り値はcloneメソッドで最もよく利用される。

public interface Cloneable{
    public Object clone();
}
 
public class CloneableImpl implements Cloneable{
    public CloneableImpl clone() {
        try {
            return (CloneableImpl)super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

CloneableImplはObjectの一つであるので、CloneableImpl clone();はObjectを返しているのと同義つまり、このメソッドはObject clone();と同等であると言える。

配列とcovariant

配列はcovariantである。IntegerはNumberであり、Integer[]はNumber[]である(共変)

Number[] n = new Integer[]{ 1, 2, 3 };      // Integer[]は、Number[]であるので代入できる。
n[0] = Double.valueOf(0d);                   // コンパイルエラーにならないが実行時例外(ArrayStoreException)

これはJava言語設計の失敗とも言われている。covariantは戻り値のようにgetするものに対しては安全だが、setする場合に危険。

ジェネリクスとcovariant

配列の反省を受けて(?)ジェネリクスはcovariantではない。IntegerはNumberであるが、List<Integer>はList<Number>ではない。

List<Number> i = new ArrayList<Integer>();    // コンパイルエラー
java/covariant.1187965007.txt.gz · 最終更新: 2011/06/23 06:02 (外部編集)