10

我一直在学习我的软件开发课程,并从一个示例中遇到了这个问题:

“为什么在 Java 方法前同时使用 static 和 final 修饰符没有意义?”

我进行了一些研究,无论我走到哪里,它都说这是不错的做法,并且有充分的理由这样做 - 例如,这个stackoverflow问题: 声明最终静态方法是个坏主意吗?

那么,这个问题本身是荒谬的,还是对这个问题有合理的答案?

(此样本文件没有给出的解决方案)

4

4 回答 4

8

static方法不能被覆盖,因为它们不是与类的实例相关联,而是与类本身相关联。例如,这是您通常调用static方法的方式:

  MyClass.myStaticMethod()

这就是调用实例方法的方式:

  new MyClass().myInstanceMethod()

final修饰符与方法一起使用以禁止在扩展类中覆盖它们。

于 2012-12-11T16:59:26.873 回答
5

因为static 方法不能被覆盖。因此,标记它没有意义final

但是请注意,static final 变量(奇怪的是,它们不是变量,因为它们不能更改)非常有用,因为它们的值可以由编译器内联。

于 2012-12-11T17:00:27.483 回答
1

静态方法可以被覆盖(尽管这不是技术术语),因为它在运行时被解析,在类链中向上搜索直到找到它。但是这个“功能”可能是一个错误;人们不使用它,人们不知道它,我们应该假装它不存在。

于 2012-12-11T17:32:46.717 回答
0

来自Java 语言规范

类方法总是在不引用特定对象的情况下被调用。尝试使用关键字 this 或关键字 super 引用当前对象是编译时错误。

因此,您不能覆盖静态方法,因为它不属于实例。因此,关键字thissuper不可用,您不能使用虚拟方法调用。如果你不能使用虚方法调用,那么 final 关键字就没有用了。

我喜欢认为编译器会看到这样的方法声明:

public class SomeClass{

    // public static classMethod() becomes
    public static [final] void classMethod(){
        //...
    }

    // and public void instanceMethod() becomes
    public void instanceMethod(SomeClass this, Object super){
        //....
    }

}

public class SomeOtherClass extends SomeClass{

    // overrides
    @Override
    public void instanceMethod(SomeOtherClass this, SomeClass super){
        //...
    }
}

然后你调用SomeClass instance = new SomeOtherClass().instanceMethod();它称为instanceMethod()of SomeOtherClass

所以编译器不需要复制方法体,只需将引用传递给线程中的当前对象。因此,当您使用虚方法调用时,实际上您是在instanceMethod使用对当前对象 ( this) 的引用来调用 ,而调用的是当前类的主体方法。

于 2012-12-11T17:05:29.030 回答