以下幾段代碼,運(yùn)行結(jié)果分別是什么?
code1:
class Sub extends Super{
public void f() {System.out.println("Sub's public f()");}
}
public class Super{
public void f() {System.out.println("Super's public f()");}
public static void main(String[] args){
Super po = new Sub();
po.f();
}
}
code2:
class Sub extends Super{
private void f() {System.out.println("Sub's private f()");}
}
public class Super{
public void f() {System.out.println("Super's public f()");}
public static void main(String[] args){
Super po = new Sub();
po.f();
}
}
code3:
class Sub extends Super{
public void f() {System.out.println("Sub's public f()");}
}
public class Super{
private void f() {System.out.println("Super's private f()");}
public static void main(String[] args){
Super po = new Sub();
po.f();
}
}
code4:
class Sub extends Super{
private void f() {System.out.println("Sub's private f()");}
}
public class Super{
private void f() {System.out.println("Super's public f()");}
public static void main(String[] args){
Super po = new Sub();
po.f();
}
}
答案:
code1: Sub's public f()
code2: Compiled error
code3: Super's private f()
code4: Super's public f()
說明:
這個(gè)問題困擾了我很久。
通過以往的學(xué)習(xí)我知道Super po = new Sub()的時(shí)候"Method is Sub's,Field is Super's"。但碰上域限定符時(shí)就又糊涂了。顯然是知其然不知其所以然。
而當(dāng)我用"javap -verbose"調(diào)試并分析日志的時(shí)候,我終于明白了:>
javap -verbose Super
Constant pool:
const #5 = class #27; // Sub
const #6 = Method #5.#21; // Sub."<init>":()V
const #7 = Method #10.#28; // Super.f:()V
public static void main(java.lang.String[]);
Code:
Stack=2, Locals=2, Args_size=1
0: new #5; //class Sub
3: dup
4: invokespecial #6; //Method Sub."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #7; //Method f:()V
由此可見,
不管是哪種情況(code1,3-4),po.f()都會(huì)無條件先調(diào)用Super.f()。
此時(shí)據(jù)我估計(jì),JVM會(huì)去Sub中尋找可訪問的相同修飾符的函數(shù)。如果找到則用其替代Super.f()運(yùn)行。
而成員變量不存在這種機(jī)制。