带通配符的Java导入不起作用,而不带通配符的导入起作用
我在学习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
- Java8 1.8.9_162
- 窗口7
+ 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时已被截断为零长度。感谢您的解释,我很高兴了解这个编译器操作。现在我明白发生了什么。