Java方法在运行时绑定
有人能帮我理解为什么第4行出现错误: 类型A中的方法calc(int,int)不适用于参数(double,double) 我知道方法是在运行时绑定的;执行哪个方法取决于调用它的对象的类型。类B中的方法计算调用。为什么编译器在类A中寻找方法Java方法在运行时绑定,java,inheritance,methods,overriding,Java,Inheritance,Methods,Overriding,有人能帮我理解为什么第4行出现错误: 类型A中的方法calc(int,int)不适用于参数(double,double) 我知道方法是在运行时绑定的;执行哪个方法取决于调用它的对象的类型。类B中的方法计算调用。为什么编译器在类A中寻找方法 非常感谢。编译器正在查找类A,因为ab是类型 您需要理解编译时多态性和运行时多态性之间的区别 方法重载是编译时多态性,编译器总是检查引用。由于ab是引用(类型)A,编译器将检查类A中的匹配方法。在这种情况下,它将找不到以double为参数的匹配方法。因此,它会
非常感谢。编译器正在查找类A,因为ab是类型 您需要理解编译时多态性和运行时多态性之间的区别
方法重载是编译时多态性,编译器总是检查引用。由于ab是引用(类型)A,编译器将检查类A中的匹配方法。在这种情况下,它将找不到以double为参数的匹配方法。因此,它会抛出一个错误。当您突然加载一个由其他人编写的、在编译过程中从未见过的by name的子类时,Java中可能存在运行时多态性。因为这可能发生,HotSpot可能不会选择内联代码或执行其他在类动态加载时必须撤消的激进优化。信不信由你,HotSpot仍然可以像这样优化和内联热方法。当动态加载子类时,它会急刹车并取消优化!它甚至可能在以后重新内联代码。真是个骗局。如果您希望代码运行得更快,请通过尽可能保持成员的私有性和最终性,为HotSpot提供更多的优化机会。这对你的设计有好处。例如,使类B成为final是一种承诺,即没有类可以进一步专门化calc方法。然后,如果您使用的是B,hotspot可以内联该方法的代码(如果它在循环中),并且可以确保这是安全有效的。因为您将变量
ab
定义为a
类型。编译器无法证明ab
实际上是aB
。谢谢。当我发布时,我将calc视为重写方法,它们不是重写方法,因为参数不同。它们是一种重载方法,尽管它们不在同一个类中。对象ab无权访问类B中的方法,因此编译器给出错误消息。
public class Any {
public static void main(String[] args) {
A ab = new **B**();
System.out.println(ab.calc(2.0, 3.1));
}
}
class A {
public int calc(int a, int b) {
return a+b;
}
}
class B extends A {
public double calc(double a, double b) {
return a+b;
}
}