如何在Java中使用静态导入`java.util.Arrays.toString`?

huangapple go评论78阅读模式
英文:

How to use a static import for java.util.Arrays.toString?

问题

考虑以下两个简单的Java代码片段:

import java.util.Arrays;
class Okay {
    public static void main(String... args) {
        System.out.println(Arrays.toString(new int[0]));
    }
}

这段代码可以正常工作。但是如果我经常使用toString,可能会尝试使用静态导入,像这样:

import static java.util.Arrays.toString;
class DoesNotCompile {
    public static void main(String... args) {
        System.out.println(toString(new int[0]));
    }
}

如果我尝试这样做,Java会认为我正在尝试调用ObjecttoString()方法,然后会抱怨toString不接受参数。这似乎很愚蠢:我在一个静态方法中,所以不应该考虑调用toString。(即使在实例方法中,我认为Java也应该得到正确的答案。)

我是否有办法修复这个问题,或者如果该名称已经被“占用”,静态导入是否根本无法工作?

英文:

Consider the following two simple java code snippets:

import java.util.Arrays;
class Okay {
    public static void main(String... args) {
        System.out.println(Arrays.toString(new int[0]));
    }
}

This works fine. But if I use toString a lot, I may be tempted to use a static import, like so:

import static java.util.Arrays.toString;
class DoesNotCompile {
    public static void main(String... args) {
        System.out.println(toString(new int[0]));
    }
}

If I try this, Java thinks I'm trying to call the toString() from Object, and then complains that toString takes no arguments. This seems silly: I'm in a static method, so that toString shouldn't even be considered. (Even in an instance method, I feel that Java should get the right answer here.)

Is there any way I can fix this, or do static imports just not work if that name is already "taken"?

答案1

得分: 3

不,这个是没有绕过的方法。

[来源:JLS 15.12,方法调用表达式](https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.12)(更具体地来自15.12.1,“确定要搜索的类或接口”)

  • 如果形式为MethodName,即仅为标识符,则:

    如果该标识符出现在具有该名称的方法声明的范围内(§6.3,§6.4.1),则:

    • 如果存在一个封闭的类型声明,其中该方法是成员,请设T为最内层的类型声明。要搜索的类或接口是T。

      这种搜索策略称为“组合规则”。它在查找嵌套类的超类层次结构中的方法之前,会在查找封闭类及其超类层次结构中查找方法。有关示例,请参见§6.5.7.1。

    • 否则,方法声明可能因为一个或多个单一静态导入或静态导入-on-demand 声明而在范围内。没有要搜索的类或接口,因为要调用的方法是稍后确定的(§15.12.2.1)。

因此,“本地”方法将始终在静态导入之前匹配。

英文:

No, there's no way round this.

[From JLS 15.12, Method Invocation Expressions] (https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.12) (more specifically from 15.12.1, "Determine Class or Interface to Search")

> * If the form is MethodName, that is, just an Identifier, then:
>
> If the Identifier appears in the scope of a method declaration with that name (§6.3, §6.4.1), then:
>
> * If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.
>
> This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See §6.5.7.1 for an example.
>
> * Otherwise, the method declaration may be in scope due to one or more single-static-import or static-import-on-demand declarations. There is no class or interface to search, as the method to be invoked is determined later (§15.12.2.1).

So, the "local" method will always be matched before the static import.

huangapple
  • 本文由 发表于 2020年5月5日 03:58:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/61600571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定