This section provides a tutorial example on how the 'javac' tool process two types of 'import' statements differently when loading required class types..
After saving all 4 source files described in the previous section, I did the following:
C:\herong>mkdir .\com
C:\herong>mkdir .\com\herong
C:\herong>mkdir .\com\herong\util
C:\herong>copy ClsA.java .\com\herong\util
C:\herong>copy ClsB.java .\com\herong\util
C:\herong>javac ImportTestA.java
ImportTestA.java:8: cannot access ClsA
bad class file: .\ClsA.java
file does not contain class ClsA
Please remove or make sure it appears in the correct subdirectory of
the classpath.
ClsA a = new ClsA();
^
1 error
What's wrong with ImportTestA.java, which uses the "On-demand type import" statement? The answer is obvious
if we use the -verbose compiler option:
C:\herong>javac -verbose ImportTestA.java
[parsing started ImportTestA.java]
[parsing completed 30ms]
[loading c:\j2sdk1.4.2\jre\lib\rt.jar(java/lang/Object.class)]
[loading c:\j2sdk1.4.2\jre\lib\rt.jar(java/lang/String.class)]
[checking ImportTestA]
[loading .\ClsA.java]
[parsing started .\ClsA.java]
[parsing completed 0ms]
ImportTestA.java:8: cannot access ClsA
bad class file: .\ClsA.java
file does not contain class ClsA
Please remove or make sure it appears in the correct subdirectory of
the classpath.
ClsA a = new ClsA();
^
[total 230ms]
1 error
C:\herong>javac -verbose ImportTestB.java
[parsing started ImportTestB.java]
[parsing completed 30ms]
[loading .\com\herong\util\ClsA.class]
[loading .\com\herong\util\ClsB.class]
[loading c:\j2sdk1.4.2\jre\lib\rt.jar(java/lang/Object.class)]
[loading c:\j2sdk1.4.2\jre\lib\rt.jar(java/lang/String.class)]
[checking ImportTestB]
[wrote ImportTestB.class]
[total 221ms]
What happened with ImportTestA.java compilation was that:
First, the compiler reached "import com.herong.util.*;", but it did not load any type definition.
Then, the compiler reached "ClsA a = new ClsA();", it started to search for the definition of "ClsA".
Then, the compiler found "ClsA.java" in the current directory.
Then, the compiler found out that "ClsA.java" is in the wrong directory path comparing with its package name.
The compilation of ImportTestB.java went very smoothly:
First, the compiler reached "import com.herong.util.ClsA;", it loaded .\com\herong\util\ClsA.class
immediately. ClsA.java has already compiled by the previous test.
Then, the compiler reached "import com.herong.util.ClsB;", it loaded .\com\herong\util\ClsB.class
immediately. ClsB.java has already compiled by the previous test.
Then, the compiler reached "ClsA a = new ClsA();", it had the definition of ClsA ready to use, no search needed.
Then, the compiler reached "ClsB b = new ClsB();", it had the definition of ClsB ready to use, no search needed.
Of course, we know how to fix the problem. Just remove ClsA.java and ClsB.java from the current directory.
"javac" will continue to search for the ClsA in the package specified in "import com.herong.util;".
This test shows us that:
"Single type import" statements load classes immediately.
"javac" searches for definitions of new types first in the loaded classes, then in the source path, and finally
in the packages specified in the "On-demand type import" statements.