导入静态,不带包名称

2022-09-04 08:33:12

请考虑以下简单的代码示例:

public class TestStaticImport {
    static enum Branches {
        APPLE,
        IBM
    }
    public static void doSomething(Branches branch) {
        if (branch == APPLE) {
            System.out.println("Apple");
        }
    }
}

如果我们尝试编译此代码,我们将收到错误消息:

java: cannot find symbol
  symbol:   variable APPLE
  location: class TestStaticImport

这可以通过引入静态导入来解决:enum

import static...TestStaticImport.Branches.*

但在这一刻,不可理解的事情(对我来说)开始了:

这个解决方案工作正常,一切都编译得很好,直到类被移动到空的根包中,即没有任何TestStaticImport

package blablabla;在这个java文件的顶部;

代码行:在我的Intellij IDEA中突出显示为有效代码(IDE的名称无关紧要,仅供参考),但是当我尝试编译此类代码时,会出现以下错误:import static TestStaticImport.Branches.*;

java: package TestStaticImport does not exist

所以,实际上有两个问题:

1)主要问题:为什么不可能从空目录?import static

2)另一种方法(如果存在)允许仅使用其名称(即 而不是 ),除了静态导入?APPLEBranches.APPLE


附言:请不要告诉我,空包装是丑陋的风格等等。这个问题只是理论问题。


答案 1

Java 语言规范禁止从未命名的包进行任何导入:

未命名包 (§7.4.2) 中的类型没有规范名称,因此在每种导入声明中对规范名称的要求意味着 (a) 无法导入未命名包中的类型,以及 (b) 无法导入未命名包中类型的静态成员。因此,§7.5.1、§7.5.2、§7.5.3 和 §7.5.4 都要求在尝试在未命名包中导入类型(或其静态成员)时出现编译时错误。


答案 2

在古代,Java发明者必须将Java类型映射到文件,以便编译器可以做一些实际的工作。他们决定将包映射到文件夹,将类型映射到文件。这效果很好。它特别为新人设定了情感背景:“我恨你。别惹我。但是我说点题外话。

但是,默认包是一个问题,因为它没有明确定义的文件夹。如果你有包,你知道某处有一个文件夹,但是默认包的文件夹名称是什么?comcom

因此,设计人员决定和默认包不混合。实际上,当您尝试导入没有包的任何内容(即 没有 和 也会失败)。请参阅如何从默认包导入类importimport TestStaticImportstatic*

因此,问题不在于静态导入,而在于您尝试从默认包导入。

就像Java中的其他一些角落案例一样,没有解决方案。

另请参阅:在Java中 - “无法导入默认包的静态成员” - 有人可以解释此语句吗?


推荐