While solving a challenge online, I observed the following behavior of java which I found a little weird. I started off by compiling a program along the following outline:
import java.io.*;
class WeirdJava
{
public static void main (String[] args)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
HashMap<Integer, Integer> map = new HashMap<Integer,Integer>();
System.out.println("Weird Java");
}
}
Notice that in the above program, there are two errors:
BufferedReader
. util
library which contains HashMap
. Now, when I try to compile the above program, the java compiler gives the error that it cannot find symbol HashMap
. Note that the declaration involving HashMap
comes after BufferedReader
. Next, I add the following import statement to the program:
import java.util.HashMap;
When I compile the program again, this time the compiler shows error
unreported exception IOException; must be caught or declared to be thrown
My questions:
It's simply the order in which source is checked by the compiler. In particular, the compiler checks for imports and resolves them before checking for code that calls methods that can raise checked exceptions.
If you run javac
with -verbose
, you'll notice that the compiler loads imported classes, in this case BufferedReader
and InputStreamReader
, then it loads the public API classes like Object
and String
:
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/io/BufferedReader.class)]]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/io/InputStreamReader.class)]
]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/lang/String.class)]]
[checking test.Test]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/lang/AutoCloseable.class)]]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/lang/System.class)]]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/io/InputStream.class)]]
[loading ZipFileIndexFileObject[C:\Dev\Java\jdk1.7.0_75\lib\ct.sym(META-INF/sym/rt.jar/java/io/Reader.class)]]
Test.java:11: error: cannot find symbol
HashMap<Integer, Integer> map = new HashMap<Integer,Integer>();
By looking at the overview in this link , loading the used classes itself is part of the first phase compilation called "Parse and Enter":
Each tree is passed to Enter, which enters symbols for all the definitions encountered into the symbols. This has to done before analysis of trees which might reference those symbols. The output from this phase is a To Do list, containing trees that need to be analyzed and have class files generated.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.