用反編譯理解程序(續)
這個題分析的不是運行結果,而是運行的機理。
import java.util.Date;
public class TestExamMethod {
public static void main(String[] args){
TestExamMethod instance = new TestExamMethod();
instance.test2();
}
public void test2(){
int x = 4;
Date date = (x > 4) ? new A() : new B();
System.out.println(date);
}
class A extends Date {
//public A(){}
public String toString(){
return "A";
}
}
class B extends Date{
//public B(){}
public String toString(){
return "B";
}
}
}
上面這段代碼在一般的IDE環境中是編譯不過去的,他會提示你A B 類型不匹配。
也許這是編譯器的一個Bug吧。[我用的是Eclipse3.1]
(在IDE下,將class B extends Date ==> class B extends A 就OK了)
其實,不改變代碼也可以進行編譯,我們直接用javac編譯,java 運行。
下面我還是利用javap -c TestExamMethod 來分析程序
public void test2();
Code:
0: iconst_4
1: istore_1
2: iload_1
3: iconst_4
4: if_icmple 18
7: new #20; //class TestExamMethod$A
10: dup
11: aload_0
12: invokespecial #21; //Method TestExamMethod$A."<init>":(LTestExamMethod
;)V
15: goto 26
18: new #22; //class TestExamMethod$B
21: dup
22: aload_0
23: invokespecial #23; //Method TestExamMethod$B."<init>":(LTestExamMethod
;)V
26: astore_2
27: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
30: aload_2
31: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/Ob
ject;)V
34: return
}
我們能看到,[7:]這裏創建對象A [18:]這裏創建對象B
但是我們並沒有看見將 A--->B 或者是將 B---->A 。這也就是說,JVM在處理?三目運算符時,
處理對象和數值類型 的方式是不一樣的。
這裏需要滿足的只是A和B可以向上轉型爲Date就OK了。
不存在數值類型轉型問題: int -- > long ---> double ........