当前位置: 首页 > 面试题库 >

为什么我不能在Java中“静态导入”“等于”方法?

钦景胜
2023-03-14
问题内容

我喜欢在这里使用这种方法:

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

唯一的缺点(例如,与Google Guava相比)是无法静态导入该方法。也就是说,这是没有用的:

import static org.apache.commons.lang.ObjectUtils.equals;

…因为我的Eclipse编译器在编写时无法正确链接该方法

equals(obj1, obj2);

错误是:

Object类型中的equals(Object)方法不适用于参数(…,…)

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

更新

这也不起作用:

import static org.apache.commons.lang.ObjectUtils.defaultIfNull;

public class Test {
  void test() {
    defaultIfNull(null, null);
    // ^^ compilation error here
  }

  void defaultIfNull() {
  }
}

javac错误消息:

Test.java:5: defaultIfNull() in Test cannot be applied to (<nulltype>,<nulltype>)
defaultIfNull(null, null);
    ^
1 error

问题答案:

JLS
15.12.1
。确定了两个原因,为什么一个方法可以“在范围内”:

  1. “ …有一个该方法是其成员的封闭类型声明”
  2. “ …由于一个或多个单一静态导入…”

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

  1. 此时,仅考虑方法的名称,稍后再签名。
  2. 上面提到的两个替代方案都与“否则”联系在一起。在第一种情况下,我们最终查看了可见方法的封闭类。在第二种情况下,我们使用静态导入。

“否则”意味着搜索范围仅限于尝试两个分支中的任何一个。首先,我们必须决定是搜索封闭类型还是使用静态导入。封闭类型具有更高的优先级,我们找到名称正确的方法(Test.defaultIfNull()),搜索到此结束。稍后,当我们发现此方法不兼容时,就没有回去尝试静态导入了。

在JLS中这种情况并不少见,方法查找的其他问题也分阶段进行,其中一个阶段的部分匹配可能会阻止在后续阶段中找到更好的匹配。固定对数与可变对数匹配是此概念的另一个示例。在所有情况下,结果是编译器不会搜索整个可能的解决方案空间,但是在做出某些决定后,整个分支将被切断并且永远不会被访问。

可以从上面得出一个经验法则:重载只能在相同类型层次结构的方法之间进行选择,而不能在与继承无关的类型方法之间进行选择。



 类似资料:
  • 问题内容: Kotlin中没有关键字。 用Kotlin 表示Java方法的最佳方法是什么? 问题答案: 您将功能放置在“伴侣对象”中。 所以像这样的java代码: 会变成 然后,您可以从Kotlin代码内部使用它,如下所示: 但是从Java代码中,您需要将其称为 (这也来自Kotlin。) 如果您不想指定位,则可以添加注释或命名伴侣类。 从文档: 类内的对象声明可以用伴随关键字标记: 可以通过仅使

  • 问题内容: 该主题充分说明了这一点-为什么不能在接口中声明静态方法的原因是什么? 上面的代码给了我以下错误(至少在Eclipse中):“接口方法ITest.test()的非法修饰符;仅允许public&abstract”。 问题答案: 这里有一些问题。第一个问题是声明静态方法而不定义它的问题。这是之间的区别 和 由于Espo提到的原因,第一个是不可能的:你不知道哪个实现类是正确的定义。 Java

  • 问题内容: 问题是在Java中为什么不能定义抽象静态方法?例如 问题答案: 因为“抽象”的意思是:“不实现任何功能”,而“静态”的意思是:“即使没有对象实例也有功能”。这是一个逻辑上的矛盾。

  • 问题内容: 问题是在Java中为什么不能定义抽象的静态方法?例如 问题答案: 因为“抽象”表示:“不执行任何功能”,而“静态”表示:“即使没有对象实例也具有功能”。这是一个逻辑上的矛盾。

  • 问题内容: 为什么我们不能在非静态内部类中使用静态方法? 如果我将内部类设为静态,则可以工作。为什么呢 问题答案: 因为内部类的实例与外部类的实例隐式关联,所以它本身不能定义任何静态方法。由于静态嵌套类无法直接引用其封闭类中定义的实例变量或方法,因此只能通过对象引用使用它们,因此在静态嵌套类中声明静态方法是安全的。

  • 问题内容: 为什么我们不能在非静态内部类中使用静态方法? 如果我将内部类设为静态,则它可以工作。为什么? 问题答案: 因为内部类的实例与外部类的实例隐式关联,所以它本身不能定义任何静态方法。由于静态嵌套类无法直接引用其封闭类中定义的实例变量或方法,因此只能通过对象引用使用它们,因此在静态嵌套类中声明静态方法是安全的。