Java 在编译期间,每个运行时绑定都是静态绑定,这是真的吗?

Java 在编译期间,每个运行时绑定都是静态绑定,这是真的吗?,java,polymorphism,overriding,overloading,static-polymorphism,Java,Polymorphism,Overriding,Overloading,Static Polymorphism,我对主题绑定很困惑。 正如我们所知,在静态绑定中,会检查引用的类型以确定绑定,而不是它所引用的对象,而在动态绑定中,会考虑引用所指向的对象的类型 class A { void show() { System.out.println("From A"); } } class B extends A { void show() { System.out.println("From B"); } } class Main

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

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-class方法show(因为引用的类型是A)。 但是在运行时,调用被解析,line1链接到A类方法show(),line2链接到B类方法,即对象类型,或者我们可以说动态绑定

因此,我的主要目的是了解以下内容

  • 动态绑定总是在静态绑定之后产生吗?或者我理解错了什么

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

  • 我们能概括一下吗


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

    考虑:

    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("");
    
    会发生什么?在编译时,编译器选择了重载
    f(对象)
    ,因为
    a
    的类型是
    a
    (只有一种方法可供选择!)。然后在运行时,由于
    a
    实际上是指
    B
    的一个实例,
    B
    调用
    f(对象)
    重载的实现,从B(对象)打印
    。我看到的一个误解是期望输出是来自B(String)
    。这是错误的,因为编译器不知道
    a
    上是否存在此重载

    动态绑定总是在静态绑定之后产生吗

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

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

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

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


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

    我们可以概括一下吗?不管怎样,每次方法调用都会有静态绑定,然后是动态绑定@是的,但是我仍然不理解你的第二个问题。为了更容易理解@sweeper,我更新了同样的问题,静态绑定更像是一种检查,而动态绑定才是真正的绑定,这样说对吗?因为在现实中,如果不创建任何对象,并且总是在运行时创建对象,那么就不会有任何绑定。我说的对吗@Sweeper?@pyskmr嗯,静态绑定仍然会影响调用哪个方法。如果一切都是在运行时完成的,那么在我的示例中,
    From B(String)
    将被打印出来。所以这不仅仅是一个检查。在final类中,由于该类是final的,所以它不会被任何类继承,所以在运行时不会有任何选择(因为final类方法不会有任何被重写的方法),它只会调用相应的方法。对吗?@pyskmr编译时为final的类不需要在运行时为final。此外,在最终类上调用的方法可能会以继承的方法结束。所以说在运行时没有选择是不正确的。唯一可以说的是,对于最终接收器类型的调用,一旦解析,目标将永远不会更改。