Java 动态绑定是必要的还是对静态绑定的改进?

Java 动态绑定是必要的还是对静态绑定的改进?,java,compiler-construction,interpreter,Java,Compiler Construction,Interpreter,java中的一个示例代码段,其中父类fun()被子类fun()覆盖: 在上面的代码中,我们知道与函数调用(obj.fun())关联的实际代码的绑定是在运行时由解释器完成的。编译期间,编译器无法将实际代码与调用绑定 我的问题是: 如果没有实例化(在创建一个类的对象之后),理想的编译器是否无法知道响应函数调用时要调用哪个函数?或者,在任何编程范式中,动态绑定都比静态绑定有优势(例如,在java中) 我的问题是泛化的。关于上面的代码,编译器根本无法知道在obj.fun()语句中调用了哪个fun(),还

java中的一个示例代码段,其中父类
fun()
被子类
fun()
覆盖:

在上面的代码中,我们知道与函数
调用(obj.fun())
关联的实际代码的绑定是在运行时由解释器完成的。编译期间,编译器无法将实际代码与调用绑定

我的问题是:

如果没有实例化(在创建一个类的对象之后),理想的编译器是否无法知道响应函数调用时要调用哪个函数?或者,在任何编程范式中,动态绑定都比静态绑定有优势(例如,在java中)


我的问题是泛化的。关于上面的代码,编译器根本无法知道在obj.fun()语句中调用了哪个fun(),还是因为无法在编译时绑定而发明了技术上的运行时绑定

Java不是唯一的解释器。现代JVM包括一个非常复杂的JIT编译器,它能够对许多调用进行设备化,包括您正在讨论的情况。当您的程序启动时,它将由执行虚拟调用的解释器执行。但如果多次执行
main
方法,JIT编译器会将其编译为本机代码。这种特殊情况非常简单,因此JIT编译器将能够用直接调用替换虚拟调用,甚至将
fun
主体内联到
main
方法中。HotSpot JIT编译器甚至可以优化精确目标方法未知的情况,但在大多数情况下,在分析阶段(前几千次调用)调用了相同的方法。它将内联最常见的情况,并保留对不太常见的情况的虚拟调用。

编译器必须遵守语言规范,即使在类似于C#和java的语言之间,语言规范也可能有所不同

如果我没有弄错的话,C#默认将方法绑定到声明的对象类型,如果您想要“真实”的运行时绑定,那么您需要声明虚拟方法。Java指定C#的“虚拟”应该始终是实例(非静态)方法的行为。语言规范中的这种差异导致编译器在编译时可以/不能或应该/不应该做什么


在这种情况下,您的实际问题有点不清楚…

在java中,您调用的方法是在编译时决定的,不是由对象的类型决定的,而是由变量的类型决定的(除非typecast)
obj
是一个类型为
class2
的变量,因此您正在调用该类的
fun
方法。有关更多信息,请阅读此问题

1)您的意思可能是:
class1obj=newclass2()和2)您的问题(对我来说)不清楚。class1 obj=new class2()和class2 obj=new class2()可以在相同的上下文中使用吗@请改进你的问题。首先,这不是有效的Java代码。此外,您正在做出您认为读者会理解的假设,例如“没有实例化(创建对象之后)”,并且不清楚您在这里假设了什么(创建对象就是实例化),还提到了解释器(Java运行时不是解释器)。因此,请解释您引用的概念,并提供定义这些概念的文章的链接。
fun()
不是一个类,而是一个方法。没有父方法或子方法,但它们是父类和子类的方法。按照惯例,类名应该以大写字母开头。我的意思是它确实是d父类中的一个方法。我的问题是广义的。关于上面的代码,编译器是否根本无法知道在obj.fun()中调用了哪个fun()语句或技术上的运行时绑定之所以被发明,是因为不可能在编译时绑定?在您特定示例中的代码中,编译器可以知道“调用了哪个fun()”,因为对象的实例化在使用“new…”的相同方法中发生,因为被调用的方法在同一个类中也有一个实现。因此对象的类型是已知的,被调用的代码是已知的,并且由于对象不能更改类型,编译器可以选择在编译时解析调用。甚至将被调用的代码全部内联。是否这样做,由编译器编写人员决定。
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();
 } 
}