Java 扩展类上的重载方法
简单的问题,奇怪的结果。我有两门课Java 扩展类上的重载方法,java,Java,简单的问题,奇怪的结果。我有两门课A和B: public class A { protected int num; public A(int n) { num = n; } public boolean f(A a) { return num == a.num * 2; } } 为什么y1.f(y2)调用A中的f()方法而不是B A y1 = new B(10); B y2 = new B(10);
A
和B
:
public class A
{
protected int num;
public A(int n)
{
num = n;
}
public boolean f(A a)
{
return num == a.num * 2;
}
}
为什么
y1.f(y2)
调用A
中的f()
方法而不是B
A y1 = new B(10);
B y2 = new B(10);
System.out.println(y1.f(y2));
它不应该在B
中调用f()
,因为B
比A
更具体吗
为什么y1.f(y2)在A中而不是在B中调用f()方法
因为y1
的编译时类型是A
重载是在编译时执行的。。。调用方法的对象的执行时间类型仅与重写相关
因此,编译器正在选择方法f(A)
,因为这是它知道它可以调用y1
的唯一f
方法(并且在参数列表中检查它是否适用)。该方法在B
中未被重写,因此在执行时,调用A
中的实现
作为一个较新的例子,请考虑这个代码:
Object x = "foo";
int length = x.length();
这甚至不会编译,因为
Object
不包含length()
方法<代码>字符串,但是编译器不考虑,因为编译时类型<代码> x>代码>是代码>对象< /代码>,而不是<代码>字符串< /代码> -即使我们可以在执行时知道x
的值将是对字符串
对象的引用。尽管@JonSkeet的答案总是毫无疑问的。。只是用字节码来支持这一点。。您还可以检查通过了什么方法,当您看到字节码25:invokevirtual\27//method com/package1/A.f:(Lcom/p ackage1/A;)Z时,您可以看到编译代码(y1.f(y2))
Object x = "foo";
int length = x.length();