为什么我不能“静态导入” “等于”方法在Java? [英] Why can't I "static import" an "equals" method in Java?

查看:142
本文介绍了为什么我不能“静态导入” “等于”方法在Java?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢这里使用这个方法:

I like using this method here:

org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)

唯一的缺点(比如Google Guava)方法。也就是说这是无用的:

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)不适用于参数(...,...)

The method equals(Object) in the type Object is not applicable for the arguments (..., ...)

为什么呢?如果在任何超类型中有一个具有相同名称(但不是相同的签名)的方法,我的静态导入方法是否不适用?这是正式在JLS中指定吗? 还是某些Eclipse编译器问题?

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? Or some Eclipse compiler issue?

UPDATE

这不起作用:

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":


  1. ...有一个封闭类型声明是成员

  2. 由于一个或多个单静态导入...

现在有两个因素导致了令人惊讶的结果:

Now two factors contribute to the surprising result:


  1. 现在只考虑方法的名称,

  2. 上面提到的两个选项与其他连接。在第一种情况下,我们最终在可见方法的封闭类中查找。在第二种情况下,我们使用静态导入。

这个其他意味着搜索范围仅限于尝试两个分支。
首先,我们必须决定是搜索一个封闭类型还是使用静态导入。封闭类型具有较高的优先级,我们找到一个正确名称的方法(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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆