带通配符的Java导入不起作用,而不带通配符的导入起作用

带通配符的Java导入不起作用,而不带通配符的导入起作用,java,import,compiler-errors,package,Java,Import,Compiler Errors,Package,我在学习Java软件包时遇到了一个问题 环境 Java8 1.8.9_162 窗口7 目录 我试图创建hoge.fuga包(仅用于学习Java),并将文件放在如下目录中 + src/ - senario.java //import hoge.fuga.* - senario.class - Foo.java //package hoge.fuga - Bar.java //package hoge.fuga + hoge/ + fuga

我在学习Java软件包时遇到了一个问题

环境
  • Java8 1.8.9_162
  • 窗口7
目录 我试图创建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时 案例:我使用
导入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,则编译源文件时不会出错

案例:我使用
导入hoge.fuga.Foo导入;进口霍格·富加·巴
编译源文件时没有错误

我想知道为什么在使用通配符时编译器的行为是不同的? 在我看来,只有当我使用通配符导入时,编译器才会检查src/目录中的源代码

这与java设置(如类路径或其他)有关吗

我想象这是一种罕见的情况,但我只是想知道为什么只有当我使用通配符时才会发生这种情况

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中更改项目设置

您的.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

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

您在
Foo.java
中是否有
公共类Foo
?文件Foo.java无法声明Bar类:这不是绝对正确的。您可以在
Foo.java
中声明
Bar.class
以及
Foo.class
我不想在这里谈论内部类。这个问题似乎与Java的基础知识有关,我不想对该语言提供的所有功能给出巨大的回应,我明白了。但是,您仍然可以在一个文件中包含多个类,只要有一个公共类用于命名该文件。在这方面,你的陈述是不正确的。谢谢你的评论和建议。现在我知道我的目录位置不够好,.java源文件应该与.class文件分开。但是,我仍然想知道为什么“仅当我使用通配符时”会建议这个错误,而不是当我使用特定的类导入时。这有什么原因吗?或者这是Java编译器的“奇怪行为”,我应该照原样去做?谢谢你的评论和建议。现在我知道我的目录位置不够好,.java源文件应该与.class文件分开。但是,我仍然想知道为什么“仅当我使用通配符时”会建议这个错误,而不是当我使用特定的类导入时。这有什么原因吗?或者这是Java编译器的“奇怪行为”,我应该照原样去做?可能只是编译器。我相信这是一个类似于手术单的问题。它看到了hoge.fuga.Foo的导入,并且知道它的一个.java文件映射到该文件,因此它等待绑定和测试错误,但是通配符导入代码将尝试通过类路径扫描尽早找到所有引用。如果您的Foo.class文件在编译时位于类路径上,那么它可能会提前扫描该类文件并中断,例如,如果它在编译Foo.java.class时已被截断为零长度。感谢您的解释,我很高兴了解这个编译器操作。现在我明白发生了什么。