共変(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.txt · 最終更新: 2007/08/24 23:16 (外部編集)
 
特に明示されていない限り、本Wikiの内容は次のライセンスに従います:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki