[英]Java runtime method selection using “super” in the subclass and “this” in the super class
我在Java的方法覆蓋/重載中發現了這種顯然很奇怪的行為,令人難以置信。 Main()
方法中的調用打印出“ B_A ”,而我希望它是“ B_B ”。
package one;
public class A {
public void method(A a){ System.out.println("A_A"); }
public void method(B b) { System.out.println("A_B"); }
public void method(){ this.method(this); }
}
package one;
public class B extends A {
public void method(A a) { System.out.println("B_A"); }
public void method(B b) { System.out.println("B_B"); }
public void method(){ super.method(); }
public static void main(String[] args) {
B bb = new B();
bb.method(); //prints B_A, expected B_B
}
}
我按以下方式分解了這個過程:
method()
super()
調用其超類的方法method()
super()
this.method(this)
被從類A內調用,但this
是指類B的一個實例,因此轉換到方法method(B b)
類B的method(A a)
呢? 我的猜測是,JVM在運行時選擇子類方法時,會開始查找重載方法的表,其中是一個固定的優先級,並且首先查找層次結構中具有更高類的參數的方法。 也就是說,它不直接用於B.method(B b)
,而是將其查找到這樣的表中,並且可以使用第一個兼容方法B.method(A a)
- 因為B是A.
另一個想法是,在類A中調用this.method(this)
直接調用B.method(A a)
,但這意味着相同上下文中的相同符號( this
)可以引用不同的對象。
任何幫助整理出來的? 提前致謝!
this.method(this)從類A中調用,但這引用了類B的實例,因此轉換為類B的方法方法(B b)。
這一步是錯誤的。 請注意,編譯器會解析重載方法(即具有相同名稱的多個方法)。 在類A
, this
具有類型A
,因此this.method(this)
調用method(A a)
。 然后在運行時B
使用該方法的實現。
另一個想法是,在A類中調用this.method(this)直接調用B.method(A a),
不,它只調用method(A a)
。 它對B
一無所知。
但這意味着同一上下文中的相同符號(this)可以引用不同的對象。
它不會也不會暗示這一點。
我還會注意到public void method(){ super.method(); }
public void method(){ super.method(); }
在B
不影響在這個問題上任何東西。
除了上面討論的答案,
B bb = new B();
bb.method(); // ... 1 ... prints B_A
A ab = new B();
ab.method(); // ... 2 ... prints B_A
A aa = new A();
aa.method(); // ... 3 ... prints A_A
不管第一和第二種情況下的參考類型,對象都是class B
。
method()
調用bb
和ab
調用super.method()
塊。
這從A class
調用method()
並將其自己的類的引用傳遞給this.method(this)
即this.method(A);
這將在運行時調用B下的方法method(A a)
(方法重寫)。
在第三種情況下, this.method(this)
調用method(A a)
類下的方法method(A a)
。
這發生在編譯時本身(方法重載)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.