简体   繁体   English

为什么Java允许我们编译名称与文件名不同的类?

[英]Why does Java allow us to compile a class with a name different than the file name?

I have a file Test.java and the following code inside it. 我有一个文件Test.java ,里面有以下代码。

public class Abcd
{
        //some code here

}

Now the class does not compile, but when I remove the public modifier , it compiles fine. 现在这个类没有编译,但是当我删除public修饰符时,它编译得很好。

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. 我知道这是一个新手问题,但我无法找到一个好的解释。

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. 许多类(如事件侦听器)仅供本地使用,最早的Java版本不支持嵌套类。 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. 如果没有“filename = class name”规则的放宽,每个这样的类都需要自己的文件,不可避免的结果是小的.java文件无穷无尽的扩散和紧密耦合的代码的散布。

As soon as Java introduced nested classes, the importance of this rule waned significantly. 一旦Java引入了嵌套类,这条规则的重要性就会大大降低。 Today you can go through many hundreds of Java files, never chancing upon one which takes advantage of it. 今天,您可以浏览数百个Java文件,而不会在利用它的文件上进行搜索。

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". 相反,门可以读作“公用事业”或“会议室”。

官方名称或MyClass.java会议室或Test.java

The Java specification states you can only have at most one public class per file. Java规范声明每个文件最多只能有一个公共类。 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. 无论文件名是什么,都允许所有非公共类具有任何名称。

I think allowing them is a prerequisite for nested classes. 我认为允许它们是嵌套类的先决条件。 Anonymous Classes in particular dramatically reduce the number of .java files required. 特别是匿名类可以显着减少所需的.java文件数量。 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) 如果不支持这一点,你需要在他们自己使用的主类的独立文件中进行大量的单一方法接口实现。(我特别想到动作监听器)

There is a good explanation of all nested classes in the Nested Classes Java tutorial on Oracle's website, which has examples of each. Oracle网站上的嵌套类 Java教程中对所有嵌套类有一个很好的解释,其中包含每个嵌套类的示例。 It also has a reason they are useful, which I'll quote: 它也有一个有用的原因,我将引用它:

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. 它增加了封装 :考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有。 By hiding class B within class A, A's members can be declared private and B can access them. 通过将类B隐藏在类A中,可以将A的成员声明为私有,并且B可以访问它们。 In addition, B itself can be hidden from the outside world. 另外,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规范,但快速搜索显示Java 1.1中添加了内部类。

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. 可能为了简化在编译期间从包外部查找公共类,有一个特殊限制,即公共类位于具有相应名称的文件中。

Note that Java is case-sensitive, but the filesystem need not be. 请注意,Java区分大小写,但文件系统不需要。 If the file's base name is "abcd", but the class is "Abcd", would that conform to the rule on a case-insensitive filesystem? 如果文件的基本名称是“abcd”,但类是“Abcd”,那么是否符合不区分大小写的文件系统的规则? Certainly not when ported to a case-sensitive one. 当然不是在移植到区分大小写的时候。

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. 或者假设您碰巧有一个名为ABCD的类,以及一个Abcd类(让我们不介意这是一个坏主意:它可能发生)并且该程序被移植到不区分大小写的文件系统。 Now you not only have to rename files, but also classes, oops! 现在你不仅要重命名文件,还要重命名类,oops!

Or what if there is no file? 或者如果没有文件怎么办? Suppose you have a Java compiler which can take input on standard input. 假设您有一个Java编译器,可以对标准输入进行输入。 So then the class has to be named "StandardInput"? 那么这个类必须命名为“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. 如果你理性地探索要求文件名遵循类名的含义,你会发现它不止一种方式是一个坏主意。

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. 还有一点,许多答案错过了指出,没有public声明,JVM永远不会知道需要调用哪些类的主要方法。 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. 在一个.java文件中声明的所有类都可以具有main方法,但main方法仅在标记为public的类上运行。 HTH HTH

Because of a java file can contains more than one class, it may have two classes in one java file. 由于java文件可以包含多个类,因此它可能在一个java文件中有两个类。 But a java file have to contain a class as the same name as file name if it contains a public class. 但是,如果java文件包含公共类,则必须包含与文件名同名的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以编译一个名称与类不同的 java 文件吗? - Can I compile a java file with a different name than the class? Java文件名与Eclipse IDE中的类名不同 - Different Java file name than the class name in Eclipse IDE Java为什么允许类名与其导入的类的名称相同? - Why does Java allow the name of the class to be same as that of a class it imports? 为什么JVM允许我们命名以字节码中的数字开头的函数? - Why does the JVM allow us to name a function starting with a digit in bytecode? 磁盘上的.class文件是否必须遵循与其Java中限定名称相同的目录结构才能运行? - Does a .class file on disk have to follow the same directory structure as its qualified name in Java for us to run it? java中的文件名和类名不同 - File name and class name different in java 如果方法名称与类不同,为什么这个java代码不起作用? - why does this java code not work if the method name is different from the class? 为什么我不能给文件名赋予不同的名字? - Why can't I give different name to class than the file name? 在某些系统中允许文件名不同于类名的javac - javac allowing file name to be different than Class name in some systems 如何编译一个.java文件,该文件被任意命名为不同于公共类名的文件 - How to compile a .java file which is been arbitrarily named different from public class name
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM