java中的示例代码段,其中父类fun()
被子类fun()
覆盖:
class class1
{
//members
void fun()
{
//some code
}
}
class2 extends class1
{
//members
void fun()
{
//some code
}
}
class overriding
{
public static void main(String args[])
{
class2 obj = new class2();
obj.fun();
}
}
在上面的代码中,我们知道与函数call(obj.fun())
关联的实际代码的绑定是在解析器的运行时期间完成的。在编译期间,编译器无法将实际代码与调用绑定。
我的问题是:
没有实例化(在创建类的对象之后)理想的编译器是否无法知道响应函数调用要调用哪个函数?或者它是完成的方式(例如在java中),动态绑定在任何编程范例中都优于静态绑定?
我的问题是概括的。关于上面的代码,编译器是否根本不知道在obj.fun()语句中实际调用了哪个fun(),或者发明了技术上运行时绑定,因为它是在编译时无法绑定?
答案 0 :(得分:1)
Java不仅是解释器。现代JVM包括一个非常复杂的JIT编译器,它能够对许多调用进行虚拟化,包括你正在谈论的案例。程序启动时,将由执行虚拟调用的解释程序执行。但是如果多次执行main
方法,它将由JIT编译器编译为本机代码。这种特殊情况非常简单,因此JIT编译器将能够直接调用替换虚拟调用,甚至将fun
主体内联到main
方法中。 HotSpot JIT编译器甚至可以优化精确目标方法未知的情况,但在大多数情况下,在分析阶段(前几千次调用)调用相同的方法。它将内联最常见的情况并保持虚拟调用不常见。
答案 1 :(得分:0)
在java中,您调用的方法是在编译时决定的,而不是由对象的类型决定,而是由变量的类型决定(除非是类型转换)。 obj
是class2
类型的变量,因此您正在调用该类的fun
方法。您可以阅读此问题以获取更多信息。 Java overloading method selection