【问题标题】:Java import with wildcard does not work while import without wildcard works带有通配符的 Java 导入不起作用,而没有通配符的导入起作用
【发布时间】:2023-04-01 13:06:02
【问题描述】:

我在学习Java包的过程中遇到了麻烦。

环境

  • Java8 1.8.9_162
  • Windows7

目录

我尝试创建 hoge.fuga 包(仅用于学习 Java)并将文件放置在如下目录中。

+ src/
    - senario.java //import hoge.fuga.*
    - senario.class
    - Foo.java //package hoge.fuga
    - Bar.java //package hoge.fuga
    + hoge/
        + fuga/
            - Foo.class
            - Bar.class

当我编译 Senario.java

案例:我使用import hoge.fuga.*; 导入

编译错误。

bad source file: .\Foo.java 
file does not contain class Foo
Please remove or make sure it appears in the correct subdirectory of the source path.  

在这种情况下,如果我从 src/ 中删除 Foo.java 和 Bar.java,源文件编译不会出错。

案例:我使用import hoge.fuga.Foo; import hoge.fuga.Bar; 导入

源文件编译没有错误。

我想知道为什么我使用通配符时编译器的行为会有所不同?

在我看来,只有当我使用通配符导入时,编译器才会检查 src/ 目录中的源代码。

这是否与 java 设置有关,例如 classpath 或 sth?

我认为这种情况很少见,但我只是想知道为什么只有在使用通配符时才会发生这种情况。

【问题讨论】:

  • 你在Foo.java中有public class Foo吗?

标签: java import compiler-errors package


【解决方案1】:

你的 .java 文件应该被移动到它们声明的包的目录中,我强烈建议将你的源文件和编译文件分成两个不同的目录以避免类路径问题。

例如,如果您预期的完全限定类名 (FQCN) 是 hoge.fuga.Foo,而您的编译根是 src/,那么您的 .java 文件应该是 src/hoge/fuga/Foo.java,而不是 src/Foo.java。

您还将 .class 文件存储在 src/ 中,这也是一个坏主意。设置编译器将类文件放在src/旁边的单独目录中,例如build/:

+ my-project/
    + src/
        - senario.java //import hoge.fuga.*
        + hoge/
            + fuga/
                - Foo.java //package hoge.fuga
                - Bar.java //package hoge.fuga
    + build/
        - senario.class
        + hoge/
            + fuga/
                - Foo.class
                - Bar.class

这将稳定您的构建并可能解决您的问题。

【讨论】:

  • 感谢 cmets 和建议。现在我明白我的目录位置不够好,应该将 .java 源文件与 .class 文件分开。但是,我仍然想知道为什么“仅在我使用通配符时”会提示此错误,而不是在我使用特定类导入时提示。这有什么原因吗?还是 Java 编译器的这种“奇怪行为”,我应该照原样处理?
  • 可能只是编译器。我确定这是一个操作订单类型的问题。它看到hoge.fuga.Foo 的导入并且知道它的一个.java 文件映射到那个,所以它等待绑定和测试错误,但是通配符导入代码将尝试通过类路径找到它可以及早的所有引用-扫描。如果您的 Foo.class 文件在编译时位于类路径中,那么它可能会提前扫描该类文件并中断,例如如果它在准备编译 Foo.java 时已经被截断为零长度。
  • 谢谢布赖恩。感谢您的解释,我很高兴知道这个编译器操作。现在我明白发生了什么。
【解决方案2】:
file does not contain class Foo

此错误表示您的 Foo.java 文件包含的类没有正确的名称。在 Java 中,你应该用定义的公共类的名字来命名你的文件。文件 Foo.java 应该声明:

public class Foo {
}

小心你的文件名,'senario.java' 是错误的命名。您应该以大写字母开头您的类名(并且文件具有相同的大小写)。这里一个 Scenario.java 可能会更好。

此外,当您为您的类声明一个包时,请确保您存在相应的文件夹层次结构。在您的情况下,带有 hoge.fuga 包的类应该在 /src/hoge/fuga 文件夹中。

您还应该配置您的项目。您的构建和源目录似乎混合在一起。

一个更好(和标准)的文件层次结构应该是

+ src/main/
    - Scenario.java
    + hoge/
        + fuga/
            - Foo.java
            - Bar.java
+ /target
    - Scenario.class
    + hoge/
        + fuga/
            - Foo.class
            - Bar.class

要配置目标目录,您必须在 IDE 中更改项目设置。

【讨论】:

  • File Foo.java 不能声明 Bar 类:这绝对不正确。您可以在 Foo.java 中声明 Bar.class 以及 Foo.class
  • 我不想在这里谈论内部类。这个问题似乎与 Java 的非常基本的知识有关,我不想对语言提供的所有功能做出巨大的回应。
  • 我明白了。但是,您仍然可以在一个文件中包含多个类,只要有一个以该文件命名的公共类即可。在这方面,你的说法是不正确的。
  • 感谢 cmets 和建议。现在我明白我的目录位置不够好,应该将 .java 源文件与 .class 文件分开。但是,我仍然想知道为什么“仅在我使用通配符时”会提示此错误,而不是在我使用特定类导入时提示。这有什么原因吗?还是 Java 编译器的这种“奇怪行为”,我应该照原样处理?
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多