在 Java 源文件(.java 文件)中,最多只能有一个 public 类,并且这个 public 类的名称必须与源文件的名称完全一致(包括大小写)。

这是一个 Java 语言规范中的硬性规定。
详细解释
为什么要有这个规定?
这个规定主要是为了简化编译和文件管理。
- 文件与类的直接映射:当你编译一个名为
MyClass.java的文件时,编译器(javac)会期望在文件中找到一个public class MyClass,这使得文件名、类名和最终生成的字节码文件(MyClass.class)之间形成了一一对应的关系,非常清晰。 - 简化命令行操作:在早期或命令行环境中,你可以直接通过
javac MyClass.java来编译,然后用java MyClass来运行主程序,如果允许一个文件里有多个public类,那么运行时该运行哪个?编译器又该以哪个类名来生成字节码文件?这会造成混乱。
一个 .java 文件中可以有什么?
除了最多一个 public 类外,一个 .java 文件中还可以包含:
- 零个或一个
public类:这是核心规则。 - 任意数量的非
public类:这些类可以是default(包私有)访问级别,也可以是protected或private内部类。 - 任意数量的接口:接口也可以是
public或非public的,但同样,一个文件中只能有一个public接口,并且其名称也必须与文件名一致,一个文件只包含一个类或一个接口。 - 任意数量的枚举:同上。
- 任意数量的顶级(top-level)
private或protected类:虽然语法允许,但这种情况非常少见,通常不推荐,因为它会破坏代码的清晰度。
代码示例
示例 1:正确的用法
文件名:Car.java

// Car.java
public class Car { // 公共类,必须与文件名一致
private String model;
public Car(String model) {
this.model = model;
}
public void drive() {
System.out.println("The " + model + " is driving.");
}
}
// 这个类是包私有的 (default),只能在同一个包内被访问
class Engine {
private String type;
public Engine(String type) {
this.type = type;
}
public void start() {
System.out.println("Engine " + type + " started.");
}
}
// 这个类是私有的,只能在 Car 类内部被访问(如果它是内部类的话)
// 但作为顶级类,它只能在同一个文件中被访问
class Tire {
public void roll() {
System.out.println("Tire is rolling.");
}
}
在这个例子中:
Car是public类,文件名必须是Car.java。Engine和Tire是非public的顶级类,它们可以被Car类在同一文件中使用,也可以被同一包下的其他类使用(Engine)或只能在文件内使用(Tire)。
示例 2:错误的用法
下面的代码会导致编译错误。
文件名:Animal.java
// Animal.java
public class Animal { // 第一个 public 类
public void eat() {
System.out.println("Animal is eating.");
}
}
public class Dog { // 第二个 public 类,编译器会报错!
public void bark() {
System.out.println("Dog is barking.");
}
}
编译错误信息:

Animal.java:9: error: class Dog is public, should be declared in a file named Dog.java
public class Dog {
^
1 error
编译器明确指出,Dog 是一个 public 类,它必须被声明在一个名为 Dog.java 的文件中。
最佳实践
尽管一个文件中可以包含多个非 public 类,但这通常被认为是不好的编程习惯("bad practice")。
推荐的规范是:一个 .java 文件只包含一个顶级类(或接口),并且这个类的名称与文件名完全一致。
这样做的好处:
- 代码清晰:每个文件只负责一个功能,易于理解和维护。
- 易于管理:文件结构一目了然,方便查找和定位代码。
- 符合规范:这是 Java 社区普遍遵循的标准,使得代码更具可读性和协作性。
你应该将上面的 Car.java 示例重构为三个独立的文件:
Car.javaEngine.javaTire.java
| 规则 | 描述 |
|---|---|
| 核心规则 | 一个 .java 源文件中最多只能有一个 public 类。 |
| 文件名 | 如果文件中包含 public 类,则文件名必须与该 public 类的名称完全一致(包括大小写)。 |
| 非公共类 | 一个文件中可以包含任意数量的非 public 类、接口或枚举。 |
| 最佳实践 | 为了代码清晰和易于维护,强烈建议一个 .java 文件只包含一个顶级类,并确保文件名与类名一致。 |
