I have a file Test.java
and the following code inside it.
我有一个文件测试。java和其中的以下代码。
public class Abcd
{
//some code here
}
Now the class does not compile, but when I remove the public
modifier , it compiles fine.
现在类不编译,但是当我删除公共修饰符时,它编译得很好。
What is the reasoning behind Java allowing us to compile a class name that is different from the file name when it is not public.
Java背后的原因是什么?它允许我们编译一个类名,当它不是公共的时候,它与文件名不同。
I know it is a newbie question, but I'm not able to find a good explanation.
我知道这是一个新手的问题,但我找不到一个好的解释。
8 个解决方案
#1
321
The rationale is to allow more than one top-level class per .java
file.
基本原理是每个.java文件允许多个*类。
Many classes—such as event listeners—are of local use only and the earliest versions of Java did not support nested classes. Without this relaxation of the "filename = class name" rule, each and every such class would have required its own file, with the unavoidable result of endless proliferation of small .java
files and the scattering of tightly coupled code.
许多类(如事件列表)只在本地使用,Java的早期版本不支持嵌套类。如果不放宽“filename = class name”规则,每个这样的类都需要自己的文件,不可避免的结果是小的.java文件的无限扩展和紧密耦合的代码的分散。
As soon as Java introduced nested classes, the importance of this rule waned significantly. Today you can go through many hundreds of Java files, never chancing upon one which takes advantage of it.
一旦Java引入嵌套类,该规则的重要性就会显著降低。现在,您可以遍历数百个Java文件,而不会去寻找一个可以利用它的文件。
#2
79
The reason is the same as for the door plates. If some person officially resides in the office (declared public) his/her name must be on the door tag. Like "Alex Jones" or "Detective Colombo". If somebody just visits the room, talks to an official or cleans the floor, their name does not have to be officially put on the door. Instead, the door can read "Utilities" or "Meeting room".
原因和门板是一样的。如果有人正式居住在办公室(公开),他/她的名字必须写在门牌上。比如“亚历克斯·琼斯”或“科伦坡侦探”。如果有人只是到房间里去,和官员谈话,或者打扫地板,他们的名字就不必正式地写在门上。相反,这扇门可以读出“公用设施”或“会议室”。
#3
29
The Java specification states you can only have at most one public class per file. In this case, the class name should match the file name. All non-public classes are allowed to have any name, regardless of the file name.
Java规范规定,每个文件最多只能有一个公共类。在这种情况下,类名应该与文件名匹配。所有非公共类都可以有任何名称,不管文件名是什么。
#4
13
I think allowing them is a prerequisite for nested classes. Anonymous Classes in particular dramatically reduce the number of .java files required. Without support for this, you would need lots of single method interface implementations in their own separate files from the main class they are used in. (I'm thinking of action listeners in particular)
我认为允许它们是嵌套类的先决条件。特别是匿名类极大地减少了所需的.java文件的数量。如果不支持这一点,您将需要在它们自己的独立文件中以及它们所使用的主类中使用大量的单个方法接口实现。(我特别想到的是行动的听众)
There is a good explanation of all nested classes in the Nested Classes Java tutorial on Oracle's website, which has examples of each. It also has a reason they are useful, which I'll quote:
在Oracle网站上的嵌套类Java教程中,对所有嵌套类都有很好的解释,其中有各自的示例。它也有一个有用的理由,我将引用它:
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
使用嵌套类的引人注目的原因包括:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
它是一种逻辑分组的方法,只在一个地方使用:如果一个类只对另一个类有用,那么将它嵌入到那个类中并将二者保持在一起是合理的。嵌套这样的“助手类”使它们的包更具流线型。
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
它增加了封装性:考虑两个*类A和B,其中B需要访问否则将被声明为私有的A的成员。通过将类B隐藏在类A中,可以将A的成员声明为私有,而B可以访问它们。此外,B本身也可以隐藏在外面的世界。
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.
它可以使代码更具可读性和可维护性:在*类中嵌套小类将代码放置在更靠近使用代码的地方。
(emphasis mine)
(强调我的)
I am not familiar with Java spec back in the early days, but a quick search shows inner classes were added in Java 1.1.
我以前不熟悉Java spec,但是快速搜索一下就会发现Java 1.1中添加了内部类。
#5
12
I look at it the other way round. The natural state of affairs would be for the programmer to pick both the class name and the file name independently. Probably in order to simplify finding public classes from outside a package during compilation, there is a special restriction that a public class be in a file with the corresponding name.
我反过来看。自然的情况是程序员可以独立地选择类名和文件名。可能为了简化在编译期间从包外部查找公共类,有一种特殊的限制,即公共类位于具有相应名称的文件中。
#6
4
Note that Java is case-sensitive, but the filesystem need not be. If the file's base name is "abcd", but the class is "Abcd", would that conform to the rule on a case-insensitive filesystem? Certainly not when ported to a case-sensitive one.
注意,Java是区分大小写的,但是文件系统不需要区分大小写。如果文件的基本名称是“abcd”,但是类是“abcd”,那么它是否符合不区分大小写的文件系统的规则?当然当移植到区分大小写的时候不会。
Or suppose you happened to have a class called ABCD, and a class Abcd (let's not get into that being a bad idea: it could happen) and the program is ported to a case insensitive filesystem. Now you not only have to rename files, but also classes, oops!
或者假设您碰巧有一个名为ABCD的类和一个名为ABCD的类(让我们不要说这是个坏主意:它可能会发生),并且程序被移植到不区分大小写的文件系统中。现在不仅要重命名文件,还要重命名类,哎呀!
Or what if there is no file? Suppose you have a Java compiler which can take input on standard input. So then the class has to be named "StandardInput"?
或者如果没有文件怎么办?假设您有一个Java编译器,它可以接受标准输入的输入。那么这个类必须被命名为"StandardInput"?
If you rationally explore the implications of requiring file names to follow class names, you will find that it's a bad idea in more than one way.
如果你理性地探究要求文件名遵循类名的含义,你会发现这不是一个好主意。
#7
3
Also one other point that many answers missed to point out is that without the public
declaration, the JVM would never know which classes' main method needs to be invoked. All classes declared in one .java file can all have main methods, but the main method is run on only the class marked as public. HTH
还有一点,许多答案都没有指出,即没有公共声明,JVM永远不会知道需要调用哪个类的主方法。java文件中声明的所有类都可以有主方法,但是主方法只在标记为public的类上运行。HTH
#8
0
Because of a java file can contains more than one class, it may have two classes in one java file. But a java file have to contain a class as the same name as file name if it contains a public class.
因为java文件可以包含多个类,所以在一个java文件中可能有两个类。但是,如果java文件包含公共类,那么它必须包含与文件名相同的类。
#1
321
The rationale is to allow more than one top-level class per .java
file.
基本原理是每个.java文件允许多个*类。
Many classes—such as event listeners—are of local use only and the earliest versions of Java did not support nested classes. Without this relaxation of the "filename = class name" rule, each and every such class would have required its own file, with the unavoidable result of endless proliferation of small .java
files and the scattering of tightly coupled code.
许多类(如事件列表)只在本地使用,Java的早期版本不支持嵌套类。如果不放宽“filename = class name”规则,每个这样的类都需要自己的文件,不可避免的结果是小的.java文件的无限扩展和紧密耦合的代码的分散。
As soon as Java introduced nested classes, the importance of this rule waned significantly. Today you can go through many hundreds of Java files, never chancing upon one which takes advantage of it.
一旦Java引入嵌套类,该规则的重要性就会显著降低。现在,您可以遍历数百个Java文件,而不会去寻找一个可以利用它的文件。
#2
79
The reason is the same as for the door plates. If some person officially resides in the office (declared public) his/her name must be on the door tag. Like "Alex Jones" or "Detective Colombo". If somebody just visits the room, talks to an official or cleans the floor, their name does not have to be officially put on the door. Instead, the door can read "Utilities" or "Meeting room".
原因和门板是一样的。如果有人正式居住在办公室(公开),他/她的名字必须写在门牌上。比如“亚历克斯·琼斯”或“科伦坡侦探”。如果有人只是到房间里去,和官员谈话,或者打扫地板,他们的名字就不必正式地写在门上。相反,这扇门可以读出“公用设施”或“会议室”。
#3
29
The Java specification states you can only have at most one public class per file. In this case, the class name should match the file name. All non-public classes are allowed to have any name, regardless of the file name.
Java规范规定,每个文件最多只能有一个公共类。在这种情况下,类名应该与文件名匹配。所有非公共类都可以有任何名称,不管文件名是什么。
#4
13
I think allowing them is a prerequisite for nested classes. Anonymous Classes in particular dramatically reduce the number of .java files required. Without support for this, you would need lots of single method interface implementations in their own separate files from the main class they are used in. (I'm thinking of action listeners in particular)
我认为允许它们是嵌套类的先决条件。特别是匿名类极大地减少了所需的.java文件的数量。如果不支持这一点,您将需要在它们自己的独立文件中以及它们所使用的主类中使用大量的单个方法接口实现。(我特别想到的是行动的听众)
There is a good explanation of all nested classes in the Nested Classes Java tutorial on Oracle's website, which has examples of each. It also has a reason they are useful, which I'll quote:
在Oracle网站上的嵌套类Java教程中,对所有嵌套类都有很好的解释,其中有各自的示例。它也有一个有用的理由,我将引用它:
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
使用嵌套类的引人注目的原因包括:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
它是一种逻辑分组的方法,只在一个地方使用:如果一个类只对另一个类有用,那么将它嵌入到那个类中并将二者保持在一起是合理的。嵌套这样的“助手类”使它们的包更具流线型。
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
它增加了封装性:考虑两个*类A和B,其中B需要访问否则将被声明为私有的A的成员。通过将类B隐藏在类A中,可以将A的成员声明为私有,而B可以访问它们。此外,B本身也可以隐藏在外面的世界。
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.
它可以使代码更具可读性和可维护性:在*类中嵌套小类将代码放置在更靠近使用代码的地方。
(emphasis mine)
(强调我的)
I am not familiar with Java spec back in the early days, but a quick search shows inner classes were added in Java 1.1.
我以前不熟悉Java spec,但是快速搜索一下就会发现Java 1.1中添加了内部类。
#5
12
I look at it the other way round. The natural state of affairs would be for the programmer to pick both the class name and the file name independently. Probably in order to simplify finding public classes from outside a package during compilation, there is a special restriction that a public class be in a file with the corresponding name.
我反过来看。自然的情况是程序员可以独立地选择类名和文件名。可能为了简化在编译期间从包外部查找公共类,有一种特殊的限制,即公共类位于具有相应名称的文件中。
#6
4
Note that Java is case-sensitive, but the filesystem need not be. If the file's base name is "abcd", but the class is "Abcd", would that conform to the rule on a case-insensitive filesystem? Certainly not when ported to a case-sensitive one.
注意,Java是区分大小写的,但是文件系统不需要区分大小写。如果文件的基本名称是“abcd”,但是类是“abcd”,那么它是否符合不区分大小写的文件系统的规则?当然当移植到区分大小写的时候不会。
Or suppose you happened to have a class called ABCD, and a class Abcd (let's not get into that being a bad idea: it could happen) and the program is ported to a case insensitive filesystem. Now you not only have to rename files, but also classes, oops!
或者假设您碰巧有一个名为ABCD的类和一个名为ABCD的类(让我们不要说这是个坏主意:它可能会发生),并且程序被移植到不区分大小写的文件系统中。现在不仅要重命名文件,还要重命名类,哎呀!
Or what if there is no file? Suppose you have a Java compiler which can take input on standard input. So then the class has to be named "StandardInput"?
或者如果没有文件怎么办?假设您有一个Java编译器,它可以接受标准输入的输入。那么这个类必须被命名为"StandardInput"?
If you rationally explore the implications of requiring file names to follow class names, you will find that it's a bad idea in more than one way.
如果你理性地探究要求文件名遵循类名的含义,你会发现这不是一个好主意。
#7
3
Also one other point that many answers missed to point out is that without the public
declaration, the JVM would never know which classes' main method needs to be invoked. All classes declared in one .java file can all have main methods, but the main method is run on only the class marked as public. HTH
还有一点,许多答案都没有指出,即没有公共声明,JVM永远不会知道需要调用哪个类的主方法。java文件中声明的所有类都可以有主方法,但是主方法只在标记为public的类上运行。HTH
#8
0
Because of a java file can contains more than one class, it may have two classes in one java file. But a java file have to contain a class as the same name as file name if it contains a public class.
因为java文件可以包含多个类,所以在一个java文件中可能有两个类。但是,如果java文件包含公共类,那么它必须包含与文件名相同的类。