我一直在学习我的软件开发课程,并从一个示例中遇到了这个问题:
“为什么在 Java 方法前同时使用 static 和 final 修饰符没有意义?”
我进行了一些研究,无论我走到哪里,它都说这是不错的做法,并且有充分的理由这样做 - 例如,这个stackoverflow问题: 声明最终静态方法是个坏主意吗?
那么,这个问题本身是荒谬的,还是对这个问题有合理的答案?
(此样本文件没有给出的解决方案)
我一直在学习我的软件开发课程,并从一个示例中遇到了这个问题:
“为什么在 Java 方法前同时使用 static 和 final 修饰符没有意义?”
我进行了一些研究,无论我走到哪里,它都说这是不错的做法,并且有充分的理由这样做 - 例如,这个stackoverflow问题: 声明最终静态方法是个坏主意吗?
那么,这个问题本身是荒谬的,还是对这个问题有合理的答案?
(此样本文件没有给出的解决方案)
static
方法不能被覆盖,因为它们不是与类的实例相关联,而是与类本身相关联。例如,这是您通常调用static
方法的方式:
MyClass.myStaticMethod()
这就是调用实例方法的方式:
new MyClass().myInstanceMethod()
final
修饰符与方法一起使用以禁止在扩展类中覆盖它们。
因为static
方法不能被覆盖。因此,标记它没有意义final
。
但是请注意,static final
变量(奇怪的是,它们不是变量,因为它们不能更改)非常有用,因为它们的值可以由编译器内联。
静态方法可以被覆盖(尽管这不是技术术语),因为它在运行时被解析,在类链中向上搜索直到找到它。但是这个“功能”可能是一个错误;人们不使用它,人们不知道它,我们应该假装它不存在。
来自Java 语言规范:
类方法总是在不引用特定对象的情况下被调用。尝试使用关键字 this 或关键字 super 引用当前对象是编译时错误。
因此,您不能覆盖静态方法,因为它不属于实例。因此,关键字this
和super
不可用,您不能使用虚拟方法调用。如果你不能使用虚方法调用,那么 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
) 的引用来调用 ,而调用的是当前类的主体方法。