【问题标题】:Is it true to say that every run time binding was a static binding during compilation?是否说每个运行时绑定都是编译期间的静态绑定?
【发布时间】:2019-10-01 13:19:32
【问题描述】:

我对主题绑定很困惑。 正如我们所知,在静态绑定中,会检查引用的类型以确定绑定,而不是它所引用的对象,而在动态绑定中,会考虑引用所指向的对象的类型。

class A
{
    void show()
    {
        System.out.println("From A");
    }
}
class B extends A
{
    void show()
    {
        System.out.println("From B");
    }
}
class Main
{
    public static void main(String[] quora)
    {
        A a1 = new A();
        A a2 = new B();

        a1.show(); //line 1
        a2.show(); //line 2
    }
}

在上面的例子中,我们可以看到在编译期间,Line1 和 line2 都会被静态绑定处理,它们会链接到 A 类方法 show( 因为引用的类型是 A)。 但在运行时,调用被解析,line1 链接到 A 类方法 show(),line2 链接到 B 类方法,即对象类型,或者我们可以说是动态绑定。

所以我的主要目的是了解以下内容。

  1. 动态绑定总是在静态绑定之后产生吗?还是我理解错了?

  2. 如果是真的,那么是不是说每个方法在运行时都是动态链接的?

  3. 我们可以概括一下吗?

【问题讨论】:

  • 我们能概括一下what吗?
  • 无论如何,每次方法调用都会有静态绑定和动态绑定。 @Sweeper
  • 确实是这样,但我还是不明白你的第二个问题。
  • 我已经更新了相同的,以便更容易理解@Sweeper

标签: java polymorphism overriding overloading static-polymorphism


【解决方案1】:

基本上,每次调用方法时,编译器都必须根据传递给方法的类型和参数确定要调用哪个重载。这是静态绑定。然后在运行时,运行时会确定要调用哪个实现的重载(此时已经决定)。

考虑:

class A
{
    void f(Object o)
    {
        System.out.println("From A");
    }
}
class B extends A
{

    void f(Object o)
    {
        System.out.println("From B (Object)");
    }

    void f(String s)
    {
        System.out.println("From B (String)");
    }
}

你做到了:

A a = new B();
a.f("");

会发生什么?在编译时,由于a 的类型为A,编译器选择了重载f(Object)(只有一种方法可供选择!)。然后在运行时,因为a 实际上是指B 的一个实例,所以Bf(Object) 重载实现被调用,打印From B (Object)。我见过的一个误解是期望输出为From B (String)。这是错误的,因为编译器不知道 a 上存在此重载。

静态绑定后总是产生动态绑定吗?

从上面代码的结果我们可以看出,答案是肯定的。静态绑定发生在编译时,动态绑定发生在运行时,所以前者总是先发生。

如果是真的,那么说每个方法在运行时都是动态链接的是真的吗?

我不确定你的意思是什么,所以希望上面的详细解释已经回答了这个问题。

不管怎样,每次方法调用都会有静态绑定,然后是动态绑定?

是的,但有时这两个过程可以很快进行,因为选择很少。当您调用方法的类是最终类时,您可能不需要在动态绑定中做出“选择”,对吗?

【讨论】:

  • 是否可以说静态绑定更像是一种检查,而动态绑定才是真正的绑定?因为实际上如果没有创建任何对象并且对象总是在运行时创建,则不会有任何绑定。 @Sweeper 我说的对吗?
  • @pyskmr 好吧,静态绑定仍然对调用哪个方法有影响。如果一切都在运行时完成,那么在我的示例中,From B (String) 将被打印出来。所以这不是只是一张支票。
  • 而在 final 类中,由于该类是最终类,所以它不会被任何类继承,所以这就是为什么在运行时不会做出任何选择(因为不会t 是最终类方法的任何重写方法)它将仅调用相应的方法。对吗?
  • @pyskmr 一个在编译时是 final 的类不需要在运行时是 final 的。此外,在最终类上调用的方法可能以继承的方法结束。所以说运行时没有选择是不正确的。唯一可以说的是,对于最终接收器类型的调用,一旦解决,目标就永远不会改变。
猜你喜欢
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多