问题描述
我喜欢在这里使用这种方法:
I like using this method here:
org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)
唯一的缺点(例如与 Google Guava 相比)是我无法静态导入该方法.IE.这是没用的:
The only drawback (compared to Google Guava, for instance), is that I cannot static import the method. I.e. this is useless:
import static org.apache.commons.lang.ObjectUtils.equals;
... 因为我的 Eclipse 编译器在编写时不会正确链接该方法
... as my Eclipse compiler will not correctly link that method when writing
equals(obj1, obj2);
错误是:
Object 类型中的 equals(Object) 方法不适用于参数 (..., ...)
这是为什么?如果在任何超类型中存在具有相同名称(但不相同的签名)的方法,我的静态导入方法是否不适用?这是在 JLS 中正式规定的吗?
Why is that? Is my statically imported method not applicable if there is a method with the same name (but not the same signature) in any of the super types? Is this formally specified in the JLS?
更新
这也不起作用:
import static org.apache.commons.lang.ObjectUtils.defaultIfNull;
public class Test {
void test() {
defaultIfNull(null, null);
// ^^ compilation error here
}
void defaultIfNull() {
}
}
javac 错误信息:
javac error message:
Test.java:5: defaultIfNull() in Test cannot be applied to (<nulltype>,<nulltype>)
defaultIfNull(null, null);
^
1 error
推荐答案
JLS 15.12.1.确定方法可以在范围内"的两个原因:
JLS 15.12.1. identifies two reasons, why a method can be "in scope":
- ...有一个封闭的类型声明,该方法是其成员"
- ...由于一个或多个单一静态导入..."
现在有两个因素导致了令人惊讶的结果:
Now two factors contribute to the surprising result:
- 此时只考虑方法的名称,稍后会考虑签名.
- 上面提到的两个选择都与否则"有关.在第一种情况下,我们最终会查看可见方法的封闭类.在第二种情况下,我们使用静态导入.
这个否则"意味着搜索范围仅限于尝试两个分支中的任何一个.首先,我们必须决定是搜索封闭类型还是使用静态导入.封闭类型具有更高的优先级,我们找到一个正确名称的方法(Test.defaultIfNull()),搜索到此结束.当后来我们发现这个方法不兼容时,就没有回头尝试静态导入了.
This "otherwise" implies that the search scope is restricted to only trying either of the two branches.First we have to decide whether we search an enclosing type or using a static import. Enclosing type has higher priority, we find a method of the correct name (Test.defaultIfNull()), search ends here. When later we find this method to be incompatible, there's no going back to trying the static import.
这种情况在 JLS 中并不少见,方法查找的其他问题也是分阶段组织的,其中一个阶段的部分匹配可能会阻止在后续阶段找到更好的匹配.固定数量与可变数量匹配是这个概念的另一个例子.在所有情况下,结果是编译器不会搜索整个可能的解决方案空间,但在做出某些决定后,整个分支将被切断并且永远不会被访问.
The situation is not uncommon in JLS, also other issues of method lookup are organized in phases, where a partial match in one phase may prevent finding a better match in a subsequent phase. Fixed-arity vs. variable arity matching is another example of this concept. The effect in all cases is that compilers do not search the entire possible solution space, but after certain decisions have been made entire branches are cut off and never visited.
从上面可以得出一个经验法则:重载只能在相同类型层次结构的方法之间进行选择,不能在与继承无关的类型方法之间进行选择.
A rule of thumb can be derived from the above: Overloading can only select among methods of the same type hierarchy, it cannot select between methods of types unrelated by inheritance.
这篇关于为什么我不能“静态导入"“等于"Java中的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!