Java – 方法在运行时绑定

huangapple go评论95阅读模式
英文:

Java - methods bind at run time

问题

Line 4 gives an error because Java uses compile-time method resolution (also known as static binding) to determine which method to call, based on the declared type of the reference variable. In this case, the reference variable ab is declared to be of type A, so when you try to call the calc method on it with arguments of type double, the compiler looks for a calc method in class A that can accept double arguments, but it doesn't find one.

Even though the object ab actually refers to an instance of class B, the compiler only considers the declared type (A) when determining which method to call. This is a fundamental concept in Java's object-oriented programming model.

If you want to call the calc method from class B with double arguments, you can either declare ab as type B like this:

B ab = new B();

Or, you can cast ab to type B when calling the method:

((B) ab).calc(2.0, 3.1);

Either way, this will resolve the error, and the calc method from class B will be called.

英文:
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;
	}
}

Can someone please help me understand why does line 4 gives error:
"The method calc(int, int) in the type A is not applicable for the arguments (double, double)"

I understand Methods are bound at runtime; which method to execute depends on the type of object on which it's called. Method calc calls in class B. Why is compiler looking for method in class A.

Many thanks.

答案1

得分: 2

编译器正在查找类A,因为ab的类型是

您需要了解编译时多态和运行时多态之间的区别。

方法重载是编译时多态,编译器总是检查引用。由于ab是A类的引用(类型),编译器将检查类A中的匹配方法。在这种情况下,它将找不到一个接受double作为参数的匹配方法。因此,它会引发错误。

英文:

Compiler is looking in class A because ab is of type

You need to understand the difference between compile-time polymorphism and runtime polymorphism.

Method overloading is compile time polymorphism and compiler always check for reference. Since ab is of reference(type) A, compiler will check for matching method in class A. In this case, it will not find a matching method which takes double as argument. Hence it throws an error.

答案2

得分: 0

在Java中,当您通过名称突然加载由其他人编写的A的子类,而在编译期间从未见过它时,可以实现运行时多态性。由于这种情况可能发生,HotSpot可能不会选择内联代码或执行其他可能需要在动态加载类时撤消的激进优化。不管信不信,HotSpot仍然可以优化和内联这样的热方法。当动态加载子类时,它会紧急制动并撤消优化!甚至可能稍后重新内联代码。相当巧妙。如果您希望代码运行更快,请通过尽可能将成员保持为private和final来为HotSpot提供更多优化的机会。这对于您的设计也有好处。例如,将类B声明为final是一个承诺,即没有类可以进一步专门化calc方法。然后,如果您正在使用B,HotSpot可以在循环中内联该方法的代码,并确保这是安全和高效的。

英文:

You can have runtime polymorphism in Java when you suddenly load a subclass of A by name that was written by someone else and which was never seen during your compilation. Because this can happen, HotSpot may not choose to inline code or perform other aggressive optimizations that would have to be undone in the event of a class loading dynamically. Believe it or not, HotSpot can still optimize and inline hot methods like this. It slams on the brakes and undoes the optimizations when a subclass is dynamically loaded! It might even re-inline the code later. Quite a trick. If you want your code to run faster, give HotSpot more chance to optimize by keeping members as private and final as possible. It’s good for your design anyway. For example, making class B final is a promise that no class can further specialize the calc method. Then if you are working with a B, hotspot can inline the code for that method if it’s in a loop and it can be sure this is safe and efficient.

huangapple
  • 本文由 发表于 2020年8月7日 03:26:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63290505.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定