当前位置: 首页 > 面试题库 >

Java中静态方法重写的奇怪情况

公良子轩
2023-03-14
问题内容

到处都写着静态方法不能被覆盖,但是当我尝试将访问说明符从public改为protected时,它给出了一个错误。例如

public class StaticOverrideFunda {

    public static void foo(){
        System.out.println("Parent Foo");
    }
}

public class B extends StaticOverrideFunda{


    protected static void foo(){
        System.out.println("Child Foo");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        B.foo();            
    }
}

它说

无法降低继承方法的可见性

所以说这是遵循最重要的规则,为什么我们说foo在B类中没有被忽略?为什么我们说它是隐藏/阴影而不是覆盖?


问题答案:

遵循 与覆盖 相同一些规则 ,但这并不意味着它
覆盖。在这种情况下,这就是JLS的8.4.8.3节
“覆盖和隐藏的要求”中的规则:

覆盖或隐藏方法的访问修饰符(第6.6节)必须至少提供与覆盖或隐藏方法相同的访问权限,如下所示:[…]

它仍然不重写,因为该方法不会被调用多态-你不能写一个电话将 有时 最终调用StaticOverrideFunda.foo有时
最终调用B.foo; 目标是在编译时完全确定的。

值得回顾第8.4.8节的其余部分,该节 重写 定义 为在实例方法上发生的事情。



 类似资料:
  • 为什么输出是"静态A"?

  • 我试图理解重载和重写静态和非静态方法是如何工作的。事实上,我试图理解这些方法如何能够和不能出现在父类和子类中。我想出了下面的规则: 我们不能重写静态方法,只能隐藏它们。通过隐藏,我们的意思是在编译时根据引用变量类型决定执行哪个方法,而不是重写(,在运行时根据实例类型选择哪个方法执行)。 例如,让,然后隐藏. 我们可以重写实例方法。 例如重写. 两个或多个具有相同签名的方法不能以静态或非静态组合形式

  • 下面示例中的实用方法仅用于说明目的。 经过一些调查,我发现在中被调用,尝试1和尝试2中的差异是由于使用Date的方法造成的精度损失。 然而,我对动态调度感到困惑。我期望调用,但调用的是。我认为实例-方法调度总是基于运行时对象。我是不是错过了一些愚蠢的东西(很可能)?

  • 我有以下代码片段: 如果我调用foo(null)为什么没有歧义?为什么程序调用foo(字符串x)而不是foo(对象x)?

  • 我不明白为什么当我尝试编译这段代码时,编译器会显示错误: 在A和B类中,两种方法之间的区别在于返回类型,我读到Java阻止重写静态方法。所以我希望编译器不会显示任何错误,因为最初没有任何重写!!

  • 我想知道: 为什么在Java中不能重写静态方法? 静态方法可以在Java中重载吗?