问题描述
最近,我正在使用一些简单的Java代码,使用 main
方法来快速测试我编写的代码。我最终遇到了两个类似的类:
公共类A {
public static void main(String [] args){
// code here
}
}
公共类B扩展A {
public static void main(String [] args)throws IOException {
// code here
}
}
我很惊讶代码停止编译,Eclipse抱怨异常IOException与A.main(String [])中的throws子句不兼容
。
嗯,两种方法都是静态的,主
函数在 B
只是隐藏 A
中的那个,所以我认为它们之间完全没有关系。在静态方法中,我们没有多态,并且在编译期间调用绑定到具体的方法实现,因此我无法理解 B中
不能抛出 main
的原因 A
中 main
签名中未声明的异常。
为什么Java设计者决定强制执行这样的约束,如果编译器没有强制执行约束,它会在什么情况下导致问题?
对于它的价值,这里是执行此规则的JLS的相关部分。
首先,给出了适用于此的方法隐藏的定义:
然后,指出:
换句话说,错误消息不是编译器中的一些疏忽,或者是对规范的误解; JLS特别努力提到 throws
子句冲突 是方法隐藏的错误(即,使用静态方法)。在每个版本的JLS中都有相同的语言可以回到1.0。
但是,我无法明确回答你的问题为什么在这种情况下存在约束。我无法想象任何需要约束的情况,因为调用哪个静态方法实现的问题总是在编译时完全解决,与实例方法不同。
p p p I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I Java语言设计不是没有公平分享有缺陷的功能(检查异常就是其中之一),这可能是另一个,但这只是猜测。
Recently I was playing around with some simple Java code using main
methods to quickly test the code I wrote. I ended up in a situation where I had two classes similar to those:
public class A {
public static void main(String[] args) {
// code here
}
}
public class B extends A {
public static void main(String[] args) throws IOException {
// code here
}
}
I was quite surprised that the code stopped compiling and Eclipse complained that Exception IOException is not compatible with throws clause in A.main(String[])
.
Well, both methods are static and the main
function in B
is just hiding the one from A
, so I thought that there is completely no relation between them. In static methods we have no polymorphism and the call is bound to the concrete method implementation during the compilation, therefore I cannot understand why main
in B
cannot throw exception that is not declared in main
signature in A
.
Why Java designers decided to enforce a constraint like this and in what situations it would cause problems if the constraint was not enforced by the compiler?
For what it's worth, here is the relevant portion of the JLS that enforces this rule.
First, §8.4.8.2. Hiding (by Class Methods) gives a definition for method hiding that applies here:
Then, §8.4.8.3. Requirements in Overriding and Hiding states that:
In other words, the error message is not some oversight in the compiler, or a misinterpretation of the spec; the JLS makes the specific effort to mention that throws
clause conflicts are an error with method hiding (i.e., with static methods). There is equivalent language to this in every version of the JLS back to 1.0.
However, I can't definitively answer your question of why the constraint is present in this case. I can't conceive of any situation in which the constraint is necessary, since the issue of which static method implementation is invoked is always completely resolved at compile-time, unlike for instance methods.
I'd bet a small amount of money that whoever first put that constraint in the langspec was simply being over-cautious, figuring it was safer to prevent something than to allow it and then later discover it causes problems. The Java language design is/was not without its fair share of flawed features (checked exceptions being one of them), and this could credibly be another, but this is just a guess.
这篇关于隐藏静态方法在子类中时的签名差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!