Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 241
Bhoot Avatar asked Jun 29 '15 18:06

Bhoot


People also ask

What are compilation errors in Java?

Compile-time errors occur when there are syntactical issues present in application code, for example, missing semicolons or parentheses, misspelled keywords or usage of undeclared variables. These syntax errors are detected by the Java compiler at compile-time and an error message is displayed on the screen.

What kind of errors might occur after successful compilation in Java?

Compile-time errors occur when syntactical problems occur in a java program due to incorrect use of Java syntax. These syntactical problems may be missing semicolons, missing brackets, misspelled keywords, use of undeclared variables, class not found, missing double-quote in Strings, and so on.

Which of the following causes a compilation error in Java?

The following are valid initializations in Java. int [ ][ ] scores = {{2,7,6}, {9,3,45}}; Hence (b) causes a compile time error.

How many types of errors are there in Java?

There are mainly two types of exceptions in Java as follows: Checked exception. Unchecked exception.


1 Answers

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.

like image 167
M A Avatar answered Oct 11 '22 03:10

M A