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

Java

Java Problem Overview


I have a file Test.java and the following code inside it.

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.

I know it is a newbie question, but I'm not able to find a good explanation.

Java Solutions


Solution 1 - Java

The rationale is to allow more than one top-level class per .java file.

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.

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.

Solution 2 - 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".

Official name or MyClass.java Meeting room or Test.java

Solution 3 - Java

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.

Solution 4 - Java

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)

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:

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

Solution 5 - Java

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.

Solution 6 - Java

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.

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!

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"?

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.

Solution 7 - Java

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

Solution 8 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2434View Question on Stackoverflow
Solution 1 - JavaMarko TopolnikView Answer on Stackoverflow
Solution 2 - JavaexebookView Answer on Stackoverflow
Solution 3 - JavaAndrei NicusanView Answer on Stackoverflow
Solution 4 - JavaJoshua McKinnonView Answer on Stackoverflow
Solution 5 - JavaPatricia ShanahanView Answer on Stackoverflow
Solution 6 - JavaKazView Answer on Stackoverflow
Solution 7 - JavahappybuddhaView Answer on Stackoverflow
Solution 8 - JavapodongfengView Answer on Stackoverflow