The compiler isn't smart enough about detecting which class files are out of date, so either manually tell it to recompile everything using javac *.java
or use a build tool such as Ant.
The reason the compiler doesn't recompile all of the classes is that it tries to be 'smart' and avoid unnecessary work by only recompiling files that changed. If a .class
file is newer than the matching .java
file, the source code hasn't changed since the previous compilation so the class isn't recompiled.
This can cause problems when there are multiple files with a chain of dependencies. Consider this simple example:
// file: A.java
public class A { public static void main(String[] args) { new B().run(); } }
// file: B.java
public class B { void run() { new C().run(); } }
// file: C.java
public class C { void run() { System.out.println("hello world"); } }
When A
is compiled for the first time, the compiler sees that it references B
, which in turn references C
. All three are compiled and all is well.
If B.java
is modified and A
is recompiled, the compiler sees that A
references B
and since B.java
is newer than B.class
it is recompiled. It doesn't recompile C
because C.java
hasn't changed. All is still well.
But if C.java
is modified and A
is recompiled the compiler sees that A
depends on B
, but since B.java
hasn't changed it is not recompiled. So the compiler never gets to C
and doesn't recompile it even though C.java
has changed.