0

为了清楚起见,我已经更详细地阐述了我的问题。

我在这里有这段代码,它使用覆盖的概念详细说明了动态绑定。

这是代码:

class Test { 
         public static void main(String [] args) 
         { 

             B b = new A();   

             b.p(10);      //  10.0
             b.p(10.0);   // 10.0
         } 
  } 
  class B
  { 
    public void p(double i)
    { 
        print(i*2); 
    } 
  } 

  class A extends B 
  { 
     public void p(double i) 
    { 
          print(i); 
    } 
  }   

现在,解释说编译器无法确定在“编译时间”期间调用哪个方法。正是在“运行时”期间,编译器才知道需要调用的方法是子类方法,因为当我们重写时,我们正在查看实际类型。

与此代码对比:

    class Test { 
         public static void main(String [] args) 
         { 

             B b = new A();   

             b.p(10);      //  10.0
             b.p(10.0);   // 10.0
         } 
       } 
  class B
 { 
   public void p(double i)() 
  { 
     print(i*2); 
  } 
} 

 class A extends B 
 { 
    public void p(int i) 
   { 
      print(i); 
   } 
}

在此示例中,编译器可以识别在编译期间调用哪个方法。编译器如何在此示例中识别而无法识别上一个示例?问题:

术语“编译时间”和“运行时间”究竟是什么意思?编译器如何在编译时无法识别需要调用的函数是子类函数?

4

9 回答 9

5

考虑以下(伪)代码:

B b = Rand() > 0.5?new A() : new B();

b.p(10);

编译器无法知道在运行时将调用哪个。

于 2013-06-25T18:06:39.007 回答
3

这很不言自明

编译时和运行时是指一个时间段


编译时间是编译器构建项目的时间。

运行时是您的项目运行的时间。


而且我假设您在询问为什么您的代码在代码运行之前不知道这B是一个。A在以下部分中:

 B b = new A();   

 b.p(10);      //  20.0
 b.p(10.0);   // 20.0

原因是编译器不会评估代码中的所有可能路径来检查这些内容,当您看到稍微复杂的实现时,这更容易理解。

 B b = new A();   

 if(...)
 {
    ...
    b = new B();
 }


 b.p(10);      //  20.0
 b.p(10.0);   // 20.0

它只知道b代码实际执行的时间。

于 2013-06-25T18:02:59.197 回答
2

运行时间的意思是“当你的程序运行时”。

编译时间的意思是“编译程序的时间”。

有些事情只有在运行时才知道。

一个例子是用户输入。

编译器无法预测用户在运行时会输入什么。

于 2013-06-25T18:03:02.283 回答
2

术语“编译时间”和“运行时间”究竟是什么意思?

编译时间是代码被编译为可执行代码(字节码)的时间。这意味着,所有文件都被链接(您通过import表达式包含),并且创建了字节码,即指令序列。

运行时间是 CPU 运行编译后的代码——字节码的时间。

编译器如何在编译时无法识别需要调用的函数是子类函数?

事实上,确实如此。如果它无法识别,那么它将不会编译,因为编译必须明确知道要调用什么方法才能为运行时准备代码。您提供的代码是有效的,并且将执行p()类中的方法。A

于 2013-06-25T18:03:57.830 回答
1
  • 编译时间:编译期间。
  • 运行时间:程序执行期间。

考虑:

List x = getsSomeList();

x可以是List接口的任何实现。

如果您调用,则在执行之前不会知道x.add(foo)正确的方法,并且有一个可以调用的实际实现。addadd

于 2013-06-25T18:04:46.680 回答
0

由于多态性,编译器无法知道要调用哪个方法,正如所说that the compiler cannot determine which method to call during"compile time",这意味着由于函数的多种形式可用,编译器决定在编译应用程序时将调用哪个版本的函数,因此它决定要调用哪个方法在程序运行时调用)。

如果您尝试调用它的函数/方法的extended/derived类从 调用该方法,如果该方法在派生类中没有重载,那么它将从 调用该方法。这就是动态绑定在面向 OOP 的语言中的工作方式。overloadsderived classbase class

于 2013-06-25T18:10:03.183 回答
0

当您使用多态性时,编译器无法知道哪个方法调用,因为您可以拥有同一方法的许多实现......因为它只能在运行时确定。

于 2013-06-25T18:05:09.087 回答
0

“编译时”和“运行时”之间的区别在于编译期间,JVM 检查程序员编写的程序中的语法、特定 Java 和其他错误。运行时是在应用程序运行期间检查的内容。

您有可能在语法上是正确的,但在运行时有很多错误。示例:程序中的拼写错误逻辑它的运行方式如何处理动画等

它依赖

于 2013-06-25T18:05:41.803 回答
-2

看起来您提供的示例不正确。

两次调用的输出都是 10.0,而不是您所说的 20.0。

于 2013-06-25T18:17:57.930 回答