考虑以下简单的代码示例:
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;
;
代码行:import static TestStaticImport.Branches.*;
在我的Intellij IDEA中突出显示为有效代码(IDE的名称无关紧要,仅供参考),但当我尝试编译此类代码时出现以下错误:
java: package TestStaticImport does not exist
所以,实际上有两个问题:
1)主要问题:为什么import static
无法从空目录开始?
2)除静态导入外,允许使用其名称(即APPLE
而不是Branches.APPLE
)对枚举字段进行代码引用的另一种方式(如果存在)是什么?
P.S。请不要告诉我,空包装是丑陋的样式等等。这个问题只是理论问题。
答案 0 :(得分:12)
Java language specification禁止从未命名的包中导入任何内容:
未命名包中的类型(第7.4.2节)没有规范名称,所以 在每种进口申报中要求规范名称 意味着(a)无法导入未命名包中的类型,并且 (b)无法导入未命名包中类型的静态成员。 因此,§7.5.1,§7.5.2,§7.5.3和§7.5.4都需要编译时 任何尝试导入类型(或其静态成员)的错误 未命名的包裹。
答案 1 :(得分:5)
在远古时代,Java发明者不得不将Java类型映射到文件,因此编译器可以做一些真正的工作。他们决定将包映射到文件夹,将类型映射到文件。这非常有效。它特别为新人设定了情感背景:“我恨你。不要惹我。”但我离题了。
默认包是一个问题,因为它没有一个定义良好的文件夹。如果您有软件包com
,您知道某处有一个文件夹com
,但默认软件包的文件夹名称是什么?
所以设计师决定import
和默认包不混合。实际上,当您尝试导入没有包的任何内容时会出现错误(例如import TestStaticImport
没有static
而*
也会失败)。见How to import a class from default package
所以问题不是静态导入,而是您尝试从默认包导入。
与Java中的其他一些极端情况一样,没有解决方案。