我不了解这种Java行为。我有两节课:
class C1 {
public void m1(double num) {
System.out.println("Inside C1.m1(): " + num);
}
}
class C2 extends C1 {
public void m1(int num) {
System.out.println("Inside C2.m1(): " + num);
}
}
这是我的主要内容:
public class Main {
public static void main(String[] args) {
C1 c = new C2();
c.m1(10);
}
}
结果是:
Inside C1.m1(): 10.0
当我期望的时候:
Inside C2.m1(): 10
另外,当我尝试完成代码语法时,我发现了这一点:
C2类的其他m1在哪里?
我还检查了Main.class的字节码,我看到了:
Compiled from "Main.java"
public class com.company.Main {
public com.company.Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class com/company/C2
3: dup
4: invokespecial #3 // Method com/company/C2."<init>":()V
7: astore_1
8: aload_1
9: ldc2_w #4 // double 10.0d
12: invokevirtual #6 // Method com/company/C1.m1:(D)V
15: return
}
字节码告诉我它将调用C1.m1(D)V(第12行)。
为什么采用C1的方法?我试图了解这种行为。
您命名的两个方法m1
没有相同的签名;超类中的一个取一个double
,子类中一个的取一个int
。这意味着编译器将根据变量的编译时类型(C1
和将调用)选择要调用的方法签名m1(double)
。由于该类在运行时C2
没有的重写版本m1(double)
,因此C1
将调用from的版本。
规则是方法签名是在编译时根据编译时类型计算的;将在运行时根据匹配的签名调度方法调用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句