1

所以我知道在 Java 中,当你有一个静态方法时,你应该使用格式调用它,ClassName.method()而不是使用与实例方法相同的结构,即:

ClassName myObject = new ClassName();
myObject.method();

但是,如果您这样做,它仍然是有效的代码并且可以工作。假设我决定在所讨论的方法是静态的情况下执行此操作,并具有以下设置:

public SuperClass {
    public static int foo(int x) {
        return x;
    }
}

public SubClass extends SuperClass {
    public static int foo(int x) { // Overriding foo() in SuperClass
        return x + 1;
    }
}

public MyDriver {
    public static void main(String[] args) {
        SuperClass myObject = new SubClass(); // Upcasting.
        System.out.println(myObject.foo(5));  // This should polymorphically print 6
    }
}

然而,屏幕上打印出来的是 5 而不是 6。为什么?

4

4 回答 4

5

静态方法仅适用于定义它们的类,并且不能被覆盖。

当您调用 时myObject.foo(5),您SuperClass.foo(5)实际上是在调用,因为您声明myObject为 a SuperClass,无论您是否将其实例化为一个。

调用静态方法的正确方法是直接从声明它的类中调用它,因此如果要调用SubClass.foo(),则必须从显式声明的SubClass实例中调用它(意味着向上转换),或者您需要SubClass.foo()像这样调用.

简单的答案是从实例调用静态方法的计算结果是从没有实例而不是实例类型的声明类型调用相同的方法。

我不确定这一点,但如果将代码编译成字节码时,实例静态方法调用实际上会编译成对声明类型的直接调用,我不会感到惊讶。

编辑:一个赞成票让我重新注意到这一点,我清理了解释以使其更加清晰,并修复了我的一些可忽略的语法错误。我希望这对未来的读者有所帮助。

于 2013-08-04T03:43:45.587 回答
1

静态方法不依赖于实例,它们属于类并且只属于类,事实上,如果您有一个静态方法,您将始终访问一个唯一的实例。

   myObject.foo(5) 

只是一个捷径,你真正在做的是

   SuperClass.foo(5)
于 2013-08-04T03:33:29.833 回答
1

您应该避免使用类的实例来调用该类的静态方法,因为它会引起混淆。如果您需要以多态方式调用任何方法,请将其设为实例方法。您不能多态地调用静态方法。调用 SuperClass 调用的原因是因为那是 myObject 在编译时的明显类。这种效果也可以在以下场景中看到:

public void doSomething(SuperClass param) {
    System.out.println("SuperClass");
}

public void doSomething(SubClass param) {
    System.out.println("SubClass");
}

public void test() {
    SuperClass myObject = new SubClass();
    doSomething(myObject);
}

如果调用 test(),SuperClass将被打印。

于 2013-08-04T03:38:46.487 回答
0

静态方法被 JVM 视为全局方法,它们根本不绑定到对象实例。顺便说一句,您只能重载静态方法,但不能重载。因此,请检查“用于覆盖和隐藏文档的 Oracle 文档”

定义与超类方法具有相同签名的方法:

-----------------------------------------Superclass Instance MethodSuperclass Static Method   
Subclass Instance Method      Overrides                                     Generates a compile-time error
Subclass Static Method            Generates a compile-time error   Hides                                         

于 2013-08-04T04:13:54.537 回答