clone()
J2SE 5.0からは、戻り値の型をObjectにしなくて良くなった。
public class Test2 implements Cloneable {
public Test2 clone() throws CloneNotSupportedException {
return (Test2)super.clone();
}
}
javapでバイトコードを見てみると面白い。
$ javap Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object implements java.lang.Cloneable{
public Test2();
public Test2 clone() throws java.lang.CloneNotSupportedException;
public java.lang.Object clone() throws java.lang.CloneNotSupportedExcption;
}
おぉ、戻り型が違うだけの同名メソッドが宣言されてる。共変メソッドの時のように、Test2 Test2.clone()は、Object Test2.clone()を呼び出しているのかと思いきや、
public Test2 clone() throws java.lang.CloneNotSupportedException; Code: 0: aload_0 1: invokespecial #2; //Method java/lang/Object.clone:()Ljava/lang/Object; 4: checkcast #3; //class Test2 7: areturn public java.lang.Object clone() throws java.lang.CloneNotSupportedException; Code: 0: aload_0 1: invokevirtual #4; //Method clone:()LTest2; 4: areturn
逆だった。ちなみにこのコード、-target jsr14でコンパイルすることが可能で、実際にJ2SE 1.4でも動く。戻り型だけが違う同名メソッドがあっても1.4は大丈夫のようだ。
public class Test3 {
public static void main(String[] args) throws Exception {
Test2 test = new Test2();
test = test.clone(); // キャスト無し!
}
}
$ d:/j2sdk1.4.2_08/bin/javac -classpath . Test3.java SHANAI@ruimon /tmp コンパイルできてしまう! $








