Search code examples
javajavac

Does the 'java' command compile Java programs?


Most websites on the internet say:

"use the javac command to compile a .java file. Then run it using the java command"

But today I tried to run a java program without javac and I got a strange result.

Here are the contents of a file called hello.java:

public class Myclass {
 public static void main(String[] args){
    System.out.println("hello world");
  }
}

Then I ran:

$ javac hello.java

Which gives me this error:

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

But when I run it without the javac command, it executed without any errors.

$ java hello.java
hello world

Does the java command also compile the program? If yes, why do we need the javac command?

The version of my java is:

openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)

Solution

  • Prior to Java 11, to run your code you have to first compile it, then you can run it. Here's an example:

    javac test.java
    java test
    

    Since Java 11, you can still do javac + java, or you can run java by itself to compile and auto-run your code. Note that no .class file will be generated. Here's an example:

    java test.java
    

    If you run java -help, you'll see the various allowed usages. Here's what it looks like on my machine. The last one is what you ran into: java [options] <sourcefile> [args] which will "execute a single source-file program".

    $ java -help
    Usage: java [options] <mainclass> [args...]
               (to execute a class)
       or  java [options] -jar <jarfile> [args...]
               (to execute a jar file)
       or  java [options] -m <module>[/<mainclass>] [args...]
           java [options] --module <module>[/<mainclass>] [args...]
               (to execute the main class in a module)
       or  java [options] <sourcefile> [args]
               (to execute a single source-file program)
    

    UPDATE:

    As pointed out by @BillK, OP also asked:

    why do we need the javac command?

    The reason we need javac is to create .class files so that code can be created, tested, distributed, run, shared, etc. like it is today. The motivation for JEP 330 was to make it easier for "early stages of learning Java, and when writing small utility programs" without changing any other existing uses.