Java Class name vs Filename
Example.java:1: error: class JavaClass is public, should be declared in a file named JavaClass.java
public class JavaClass{
^
1 error
The very well known example you must have faced if you have worked with the command line. It states that the JavaClass class is public and is inside the Example.java file, which is not allowed in Java, i.e. it looks like:
// File name -> Example.javapublic class JavaClass{
public static void main(String[] args){
System.out.println("Print Statement");
}
}
So what's the issue? Before going into that, let’s see if non-public class be used in a similar way.
Non-Public class with a different name than .java file:
Say we will have a non-public class names JavaClass in Example.java file(Note the file name and class is still different).
// File name -> Example.javaclass JavaClass{
public static void main(String[] args){
System.out.println("Print Statement");
}
}
Now if we try to execute it:
javac Example will compile it fine.
java Example will not work.
java JavaClass will work, as shown below:
javac Example.java: It tries to locate if the file with name Example.java exists in the directory we are in(C:\Users\Administrator\Desktop in the pic above).
If it founds it tries to compile it, as c in javac stands for the compiler. Now as you must be knowing, the compiler converts the .java file into .class file. Now as the java class is with name JavaClass it will create a new file JavaClass.class in the same directory. This is what javac command does, creates the .class file with the same name as the class itself(and necessarily not the file name).
java Example: The java command tries to execute the .class file. Note that the JCM cant execute the .java file, but it can only execute the bytecode. So java Example means it tries to find the file Example.class in the same directory, and then execute. And as the error says in the pic above, it is unable to find it as there was no Example.class generated but it was JavaClass.class instead, and hence the error.
java JavaClass: This will try to find the file JavaClass.class and execute it. As it was there, it executes fine and the print statement was printed. So even if the class had the different name than the file, we can still execute it, but the overhead lies with the user now, that he has to type in 2 different names for javac command and java command.
javac Example.java and java JavaClass
So it's a good practice to keep the So fsame names always for the file name and the class name.
java JavaClass.class: this is the syntax error, as we need to put the extension, else it will try to search for javaClass.class.class which is not there.
So if we have a non-public class with a different name than the file name, then it will work, but its then up to the user to type in the correct names while executing java and javac commands.
Public class in .java File:
Now we come to the second part of this use case. Say we have the public class instead as:
// File name -> Example.javapublic class JavaClass{
public static void main(String[] args){
System.out.println("Print Statement");
}
}
Trying javac will not work as:
This is not allowed in Java.
Let's see why this is forbidden. Consider an example where we have multiple classes in the same file:
// Inside Example.java file:public class Example{
public static void main(String[] args){
System.out.println("Print Statement 1");
}
}class JavaClass1{
void method(){
System.out.println("Print Statement 2");
}
}class JavaClass2{
void method(){
System.out.println("Print Statement 3");
}
}class JavaClass3{
void method(){
System.out.println("Print Statement 4");
}
}
Now if we compiled this file, it will generate 4 different files:
JavaClass1.class,
JavaClass2.class,
JavaClass3.class and
Example.class.
And now if we try to execute it, the JVM has to look into all the different classes to find the entry point(main method) to run. Its because that main method can be in any of these. So to save it from all this overhead, Java allows us to have only a single public class in each file so that when that is run, it knows where to look for in that class for the entry point, i.e. the public class — Example.class in the above example.
So in any .java file, if we can have only one public class because if it had allowed multiple public classes then also its the same problem, it won't know which class to look for in them.
So if any file has a public class with the same name as file name, we can directly execute javac FileName.java and then go for java FileName, and it will work because it knows that FileName.java file will have a public class FileName which is to be considered as the Entry point. So if this convention is broken, the javac itself throws the error.