Skip to main content

Why Single Java Source File Can Not Have More Than One public class

According to Java standards and common practices we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints,
  • Each source file should contain only one public class and the name of that public class should be similar to the name of the source file.
  • If you are declaring the main method in your source file then main should lie in that public class
If there is no public class in the source file then main method can lie in any class and we can give any name to the source file.

If you are not following 1st constraint then you will receive a compilation error saying “The public type A must be defined in its own file”. While if you are not following the second constraint you will receive an error “Error: Could not find or load main class User” after execution of the program and if you will try this in Eclipse then you will not get the option to execute the program.

Here we are talking about only top level classes, we can declare more than one public inner class.

Why only one public class per source file

Now we know that we can’t declare more than one public file in the single source file, Now we will look at why we can’t do this or why it is not allowed in Java.
Well, actually it is an optional restriction according to Java Language Specification (Section 7.6, Page No. 209) but followed by Oracle Java compiler as a mandatory restriction. According to Java Language Specification,

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit.
This restriction makes it easy for a Java compiler to find a named class within a package.
In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.

For example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket , and the corresponding object code would be found in the file Toad.class in the same directory.

Above clarification is little bit typical to understand, So let’s replace the “type” word with actual a class Toad to get more clarification,

Java compiler may give an error if Toad class is not found in Toad.java and either of following is true
  • Toad class is referred in other classes in same package.
  • Toad class is declared public.
This restriction implies that there must be at most one such Toad class per compilation unit.
And the reason behind this is,
This restriction makes it easy for a compiler for the Java programming language or an implementation of the Java virtual machine to find a named class within a package.

To get more clear picture let's imagine there are two public classes public class A and public class B in a same source file and A class have reference to the not yet compiled class B. And we are compiling (compiling-linking-loading) class A now while linking to class B compiler will be forced to examine each *.java files within the current package because class B don’t have it’s specific B.java file. So In above case, it is a little bit time consuming for the compiler to find which class lies under which source file and in which class the main method lies.
So the reason behind keeping one public class per source file is to actually make compilation process faster because it enables a more efficient lookup of the source and compiled files during linking (import statements). The idea is if you know the name of a class, you know where it should be found for each classpath entry and no indexing will be required.

And also as soon as we execute our application JVM by default looks for the public class (since no restrictions and can be accessible from anywhere) and also looks for public static void main(String args[]) in that public class. Public class acts as the initial class from where the JVM instance for the Java application (program) is begun. So when we provide more than one public class in a program the compiler itself stops you by throwing an error. This is because later we can’t confuse the JVM as to which class to be its initial class because only one public class with the public static void main(String args[]) is the initial class for JVM. 

But why can we declare more than one non-public class (default access) in a single source file

Although there is no particular specification or reference to point why it is allowed to have more than one non-public class per source file. Presumably, the point is that developers are more likely to want to find the source code for a public class than a non-public one because developers don’t work on the same package provided by others so they don’t need to know the non-public classes. So compiler should not worry too much about linking non-public class because these are private to package.
But we should declare every class in its own file because it we will make the source short, simple, well organised and easy to understand.


Comments

  1. I really appreciate information shared above. It’s of great help. If someone want to learn Online (Virtual) instructor lead live training in LIFERAY, kindly contact us http://www.maxmunus.com/contact
    MaxMunus Offer World Class Virtual Instructor led training on LIFERAY. We have industry expert trainer. We provide Training Material and Software Support. MaxMunus has successfully conducted 100000+ trainings in India, USA, UK, Australlia, Switzerland, Qatar, Saudi Arabia, Bangladesh, Bahrain and UAE etc.
    For Demo Contact us.
    Saurabh Srivastava
    MaxMunus
    E-mail: saurabh@maxmunus.com
    Skype id: saurabhmaxmunus
    Ph:+91 8553576305 / 080 - 41103383
    http://www.maxmunus.com/


    ReplyDelete
  2. Thanks for sharing this good blog.This is very important and imformative blog for Java . very interesting and usefulblog
    Java Online Training Hyderabad

    ReplyDelete

Post a Comment

Popular posts from this blog

Why an outer Java class can’t be static

In a previous blog , I talked about why we can not define an outer class using private or protected keywords. If you have not read it, please go ahead and give it a look. I this article I will talk what is the use of the static keyword, why an outer Java class can’t be static, why it is not allowed in Java to define a static outer class. In order to understand that first, we need to understand what is the static keyword used for, what purpose it solves and how does it works. What does static keyword do Every Java programmer knows that if we need to define some behavior (method) or state (field) which will be common to all objects we define it as static. Because static content (behavior or state) does not belong to any particular instance or object, it will common to all objects and all objects are free to change any static field and every change will be visible to every object. We do not need to create any object of the class to access a static field or method, we can directly refer a

Creating objects through Reflection in Java with Example

In Java, we generally create objects using the new keyword or we use some DI framework e.g. Spring to create an object which internally use Java Reflection API to do so. In this Article, we are going to study the reflective ways to create objects. There are two methods present in Reflection API which we can use to create objects Class.newInstance() → Inside java.lang package Constructor.newInstance() → Inside java.lang.reflect package However there are total 5 ways create objects in Java, if you are not aware of them please go through this article 5 Different ways to create objects in Java with Example . Both Class.newInstance() and java.lang.reflect.Constructor.newInstance() are known as reflective methods because these two uses reflection API to create the object. Both are not static and we can call earlier one on a class level object while latter one needs constructor level object which we can get by using the class level object. Class.newInstance() The Class class is the mo