简体   繁体   English

java编译中出现意外的错误顺序

[英]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. 在线解决挑战时,我发现了java的以下行为,我发现它有点奇怪。 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 . 我没有处理BufferedReader可能抛出的异常。
  • I have not imported standard util library which contains HashMap . 我没有导入包含HashMap标准util库。

Now, when I try to compile the above program, the java compiler gives the error that it cannot find symbol HashMap . 现在,当我尝试编译上面的程序时,java编译器给出了它无法找到符号HashMap的错误。 Note that the declaration involving HashMap comes after BufferedReader . 请注意,涉及HashMap的声明位于BufferedReader之后。 Next, I add the following import statement to the program: 接下来,我将以下import语句添加到程序中:

import java.util.HashMap;

When I compile the program again, this time the compiler shows error 当我再次编译程序时,这次编译器显示错误

unreported exception IOException; 未报告的异常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 : 如果使用-verbose运行javac ,您会注意到编译器加载了导入的类,在本例中为BufferedReaderInputStreamReader ,然后它加载了像ObjectString这样的公共API类:

[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": 通过查看此链接中的概述,加载已使用的类本身是第一阶段编译的一部分,称为“Parse and Enter”:

Each tree is passed to Enter, which enters symbols for all the definitions encountered into the symbols. 每个树都传递给Enter,它输入符号中遇到的所有定义的符号。 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. 此阶段的输出是待办事项列表,其中包含需要分析并生成类文件的树。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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