1

我有两个问题 1 覆盖 2 编译时绑定
嗨我想知道如何检查 sh() 是否变为覆盖

方法参数在方法覆盖中起任何作用吗?

为什么我们说静态方法在编译时绑定,但实际上静态方法在类加载时分配内存?当我使用 javac 工具时,这意味着我使用编译器并且我编译了一个 java 文件,所以那一刻静态内存不分配,静态内存分配一个类加载时间,那么为什么说静态方法使用编译时绑定

类加载时间与编译时间相同吗?我很困惑

我知道这里的方法签名是不同的,所以这里没有比这里实际发生的覆盖解释

class A
    {
        void sh(char x){
        System.out.println("value of x :  "+x);
        }
    }
    class B extends A
    {
        public void sh(int x)
        {
            System.out.println("value of x"+x);
        }
    }
    class C
    {
        public static void main(String...Aa) /* ??? */
        {
            A a1=new B();
            //a1.show();
            a1.sh('a');
            a1.sh(10);
        }
    } 
4

2 回答 2

4

Java语言规范指出

在类 C 中声明的实例方法 m1 覆盖在类 A 中声明的另一个实例方法 m2,前提是满足以下所有条件:

  • C 是 A 的子类。

  • m1 的签名是 m2 签名的子签名(第 8.4.2 节)。

  • 任何一个:

    • m2 是公共的、受保护的或在与 C 相同的包中声明为具有默认访问权限,或

    • m1 覆盖方法 m3(m3 不同于 m1,m3 不同于 m2),这样 m3 会覆盖 m2。

  • 此外,如果 m1 不是抽象的,则称 m1 实现了它覆盖的抽象方法的所有声明。

的定义在subsignature这里。你问

方法参数在方法覆盖中起任何作用吗?

根据上述,是的,非常如此。你的签名必须匹配。换句话说

public void sh(int x)

不是压倒一切的

void sh(char x){

为什么我们说静态方法在编译时绑定,但实际上静态方法在类加载时分配内存?

在编译时,方法调用在引用的静态或声明类型上解析。换句话说,如果类型没有声明这样的方法,程序将无法编译。对于static方法。如果该方法是static,则该方法会立即解析并绑定到调用它的类型。如果它是一种instance方法,则绑定是通过多态性动态解析(后期绑定)的。

这些都与类加载或分配内存无关。

于 2013-09-27T19:49:34.487 回答
1

我不清楚你在问什么。但是,当Bextends时AB也会继承该sh(char x)方法。该sh(int x)方法不会覆盖它,因为参数类型不同。所以一个类的对象B将有两个不同的方法命名sh

但是,在您的代码中,您声明a1为 type A。尽管它将(在运行时)引用 type 的对象,B但据编译器所知,它仍然是 type A。因此,您可以应用于此对象的方法是在中声明的方法A(及其超类,如果有的话,但它没有,除了Object)。您拥有的唯一方法(除了Object方法)是sh(char x).

所以当你说

a1.sh('a');
a1.sh(10);

编译器会将其视为参数是 a char,因为它会查看的唯一方法是带char参数的方法。这意味着a1.sh(10)sh使用A“字符 10”作为参数调用 - 编辑:不,它不会;我试过了,编译器不会让我char自动将 10 转换为 a 。

于 2013-09-27T19:46:28.927 回答