65

In any Java file, why can we have only one public class whose name is same as the Java file name?

jjnguy
  • 136,852
  • 53
  • 295
  • 323
Jenesh
  • 659
  • 1
  • 6
  • 3
  • 62
    **Because [he](http://en.wikipedia.org/wiki/James_Gosling) said so!!** – jjnguy Aug 26 '10 at 18:57
  • 2
    To allow the compiler found easily the class definition. Its easier to compile that way. I don't have a reference ( that's why this is a comment ) but I think the answers below point to that. – OscarRyz Aug 26 '10 at 19:01
  • 2
    In other words, invent your own programming language if you disagree :) – BalusC Aug 26 '10 at 19:01

13 Answers13

37

It forces all Java code to be organized in a certain way, which in the long run helps improve code readability.

The Java designers chose a strict approach that enforces their idea of good design practices, and this is part of that theme. Contrast that with the anything-goes attitude in Perl.

nbro
  • 15,395
  • 32
  • 113
  • 196
Mike Baranczak
  • 8,291
  • 8
  • 47
  • 71
  • 1
    +1, totally agree, hell I miss this in C#. Even if I always use a separate file for each class/enum/struct I have seen horrible things :-) – Darin Dimitrov Aug 26 '10 at 19:01
  • 3
    It should be even more strict and also apply to non-public classes. Most people do it the right way, but some still manage to make a mess by putting many default visible classes in one file. – starblue Aug 26 '10 at 21:34
  • 2
    Do you have a citation to support the claim that code readability was the reason why the designers chose this restriction? – Rohit Dec 21 '11 at 13:39
  • @starblue Don't get private classes and *inner* classes mixed up. Inner classes (that are not static; which, I agree, should be in their own file) allow direct access of the parent object, and all instances must be instantiated with an `object.Class` instead of just a `Class`. In contrast, they are functionally very different. – Qix - MONICA WAS MISTREATED Jan 16 '13 at 07:48
  • @Qix I'm not talking about inner classes. – starblue Jan 16 '13 at 09:44
  • So you're saying private, non inner java classes are different than public, non inner classes (other than scope) how? – Qix - MONICA WAS MISTREATED Jan 17 '13 at 00:49
  • @Qix: If a class exists for the sole purpose of holding data returned by a method of another class, but instances of that class have no reason to hold a reference to the object which created them, where should it most logically be declared, if not in the file which creates it? – supercat Dec 30 '13 at 19:12
  • @starblue Are you suggesting that it should be "one class, one file" regardless of a class's accessibility? – Nicholas Cousar Jul 11 '21 at 18:14
  • Yes, for classes which are default visible, i.e. visible inside the package (not inner classes). It's the way people and tools expect it and so the easiest to work with. I think at the time I wrote that more than ten years ago I had in mind some especially painful case, but I don't remember any specifics now. – starblue Jul 12 '21 at 17:45
19

According to this source, it is for efficient compilation :

In the sidebar it explains why: "This restriction is not yet enforced by the compiler, although it's necessary for efficient package importation"

It's pretty obvious - like most things are once you know the design reasons - the compiler would have to make an additional pass through all the compilation units (.java files) to figure out what classes were where, and that would make the compilation even slower.

The same applies also for imports of source files in IDEs. Another reason would be reasonable source sizes.

Timo Westkämper
  • 21,824
  • 5
  • 78
  • 111
9

These are the rules. Although it is not quite true. You can define internal classes inside you "main" class like this:

public class A {  
   public class B {  
       ...  
   }  
}
Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
spbfox
  • 939
  • 4
  • 8
3

We can have only one top level public either class or interface in any java compilation unit ( .java source file ).

But there can be any number of default classes/interfaces per src file.

why:

JLS leaves the option to the java compiler. And most of the compiler implementations force to have file name same as :

(1) the public class/interface name

(2) if there is a main method and no public class then any name

(3) If there is main method and public class then main method should be in that public class

(4) if there is no public class and no main method then any valid name which may or may not be matching with the class/interface names in the file.

From (2): If two public classes allowed, we should give the file two names which is terribly meaningless to file system. From (3): If two public classes allowed, we should have two main methods which is terribly meaningless to java

Hence a Java source file can have one only public class.

I think the above 4 points are forced by compiler to make the job of both compiler and jvm to find particular java source file or class file easy-so-quick for the compilation/loading/linking. Java has such built in restrictions which developers should follow to have better programming.

Source: My readings and understanding.

Venkataswamy
  • 1,019
  • 7
  • 7
3

To understand the basic reason behind these restrictions, let's suppose compiler doesn't give compile error for not naming file name same as public class name.

Suppose there is a package A

        A
      /   \
file1.java   file2.java

file1.java

package A;

class file1
{
  public static void main(String args[])
  {

  }
}

public class file3
{
 public static void main(String args[])
 {

 }
}

Now as we know that a public class can also be accessed outside the package, now it will become the responsibility of a developer to make it accessible to the outside world. Let's see how:

Suppose package A is containing only Java files(no class files) and some class outside the package A tries to access public class file3, compiler will first try to find file3.class ( not available ), then it will try to find file3.java ( not available ). So even though file3 class is public in nature, it is not visible to the outside world. So if a compiler puts the restriction that if a file is containing public class, it should be named same as the public class name, then above issue can be resolved and the developer won't have to think of exposing public class to the outside world.

Compiler also puts the restriction that there should be atmost one public class per Java file, so that every public class can be accessed by the outside world.

prat
  • 133
  • 1
  • 7
3

Courtesy of Dr Heinz Kabutz and his excellent newsletter....

Why is each public class in a separate file?

This is a question that I have frequently been asked during my courses. Up to now I have not had a good answer to this question. In section 1, we read: "Although each Oak compilation unit can contain multiple classes or interfaces, at most one class or interface per compilation unit can be public".

In the sidebar it explains why: "This restriction is not yet enforced by the compiler, although it's necessary for efficient package importation"

It's pretty obvious - like most things are once you know the design reasons - the compiler would have to make an additional pass through all the compilation units (.java files) to figure out what classes were where, and that would make the compilation even slower.

Joel
  • 29,538
  • 35
  • 110
  • 138
1

Java utilizes this convention to find class/interface bytecode by starting at the classpath and scanning for the package hierarchy in subdirectories. Filesystem representation of this hierarchy also enforces some basic rules.

  1. Any two Java classes or interfaces in the same package cannot have the same name. File names would conflict.
  2. Any two Java packages in the same parent package could not have the same name. Folder paths would conflict.
  3. A class has visibility to all classes in the same package without modification to the classpath.
Aaron
  • 999
  • 2
  • 9
  • 21
1

To have an understanding between the compiler and the programmer.It is a rule that the source code must have atmost one public class and that class must contain the main function.So without any confusion/restriction the compiler can access(public) the class and name the class name to the class file.Also since this class contains the main(), executing the class file will give correct flow

1

Public modifier with a class is exposed to the world that means any other class which is outside of the package can also access it to resolve dependency. Now this dependency chain containing multiple classes are verified two times - one is while compilation ( one level of dependency is verified) & other one is while execution ( whole dependency chain is verified ).

Now suppose there is public class (class A) whose source file name is something different from class name. Now if some other class (say class B) depends on it , then while compilation of class B , java compiler will surely check where that class A is located & for that compiler has to go thru all the packages in search of class A ,which is time consuming.

Now suppose in the same scenario we give source file name of class A as A.java , then while compiling class B , compiler will search for class A & for that it only need to find source file whose name is A.java , so it doesn't need to go thru all packages ( which may contain multiple classes) it will now only search that package in which a source file A.java is present.

So from compilation time , performance point if view one source file should have one public class.

Sambeet
  • 193
  • 3
  • 10
0

It enables a more efficient lookup of source (.java) and compiled (.class) files during compilation (import directive) and a more efficient classloading during execution. The idea being: if you know the name of a class, you know where it should be found for each classpath entry. No indexing required.

gawi
  • 13,940
  • 7
  • 42
  • 78
  • Wrong about the runtime class-loading. If I have a file X.java that contains public class X and non-public class Y, then the compiler will create two files, X.class and Y.class. The class loader doesn't care whether the classes are public, and it has no way of telling whether they came from the same file. – Mike Baranczak Aug 26 '10 at 19:15
  • This does not impact the class loader lookup performance. Once compiled, it's not relevant to know from which source file the class comes from. For the compiler however, a reference to the not-yet-compiled class Y will force the compiler to examine each *.java files within the current package (typically, all the source files of the directory of the package). That's rather a minor detail. – gawi Aug 26 '10 at 20:11
0

I think that this may be a possible reason. There can be only one public class in a java file because the name of java file is same as the name of public class.And obviously we can't have a file with two different names.

0

It is how it has been designed and I am not sure if the reason is documented. But here is a good reason on why it is done that way. Let's assume we have two public classes Y & Z in a file named Y.java. Now, let's assume a different class X is using Z. Now, when we compile X, the compiler first tries to locate Z.class and if it cannot find it, then it tries to locate Z.java so that it can compile it automatically. But, since we only have Y.java, the class Z cannot be located and hence we get a compilation error. So, we do need to place them in separate files.

Akash sharma
  • 489
  • 4
  • 5
-1

Class A{


} public Class B{


} So this is correct becoz A is not public and compiler will not confuse that which class compiler should execute.

public Class A{


} public Class B{


}

So this is incorrect becoz here compiler get confused which class should execute becoz both are public.

Dharman
  • 30,962
  • 25
  • 85
  • 135