用反编译理解程序(续)
这个题分析的不是运行结果,而是运行的机理。
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 ........