简体   繁体   中英

Unexpected order of errors in java compilation

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:

  • I have not handled exceptions which might be thrown by BufferedReader .
  • I have not imported standard 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:

  1. Why is this error not thrown in the previous compilation attempt?
  2. The order in which compilation error comes does not seem natural. What are the compiler design principles which come into play during this routine?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM