'Java program runs yet compilation fails

I wrote a Java program whose filename was (intentionally) different from the class I wrote inside the file. The javac command failed as expected on both CMD and WSL. The java command however worked and ran my print statement. I wrote the code intentionally this way so there is no way it was a previously compiled version of the code. The following code was written in a file called "explainJava.java" (notice the filename is different from the class name).

public class explain{
    public static void main(String[] args) {
            System.out.println("Java is weird");
    }
}


Solution 1:[1]

I've had to google this myself, but I think I've found an explanation in this article.

According to that source as of Java 11 java is capable of compiling a single source file into memory.

What I conclude from that: When the file is compiled into memory and not written to disk it obviously cannot have a file name. If there is no filename there is no such thing as a wrong filename, therefore the code executes.

Please also note that the restriction of having to name a file like the public class within that file is more of a design decision to make work for the compiler easier/ faster. It is not a physical restriction so to speak. Have a look at the following thread for more details.

Solution 2:[2]

If you put this code:

public class explain {
    public static void main(String[] args) {
        System.out.println("Java is weird");
    }
}

into a file named explainJava.java, and then compile it with this:

javac explainJava.java

you will get an error that correctly informs you that your filename ("explainJava") and the class defined inside that file ("explain") do not match:

explainJava.java:1: error: class explain is public, should be declared in a file named explain.java
public class explain{
       ^
1 error

If you run this command:

$ java explainJava.java 
Java is weird

you see expected output, because you're skipping the explicit compilation step (that is, you aren't running javac first) and instead relying on behavior introduced in Java 11 that allows you to compile+run in a single step. Here's an explanation: Does the 'java' command compile Java programs?

So the answer is to either:

  • rename your file to match the class, so change the filename to "explain.java", or
  • rename the class to match the file, change public class explain to be public class explainJava

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mushroomator
Solution 2 kaan