【发布时间】:2009-12-30 10:19:01
【问题描述】:
Java 编译器使用什么搜索顺序来解析以下类中的Foo?
class Test
{
Foo f;
}
实证检验显示以下搜索顺序:
- 嵌套类
- 超类嵌套类
- java.lang.* 类
- 其他?
但我想知道Java Language Specification 中讨论的位置。
【问题讨论】:
标签: java compiler-construction
Java 编译器使用什么搜索顺序来解析以下类中的Foo?
class Test
{
Foo f;
}
实证检验显示以下搜索顺序:
但我想知道Java Language Specification 中讨论的位置。
【问题讨论】:
标签: java compiler-construction
我认为没有您所说的搜索顺序。相反,我认为这条规则适用:
6.5.5 类型名称的含义 TypeName 确定如下。
6.5.5.1 简单类型名称 如果类型名称由单个标识符组成, 那么标识符必须出现在 恰好一个可见的范围 声明具有此名称的类型, 或发生编译时错误。这 类型名称的含义就是那个类型。
在这种情况下,导入算作声明;见 JLS 6.1。然而,复杂的因素是影子规则(JLS 6.3.1),它说某些类型的声明(在这种情况下是类型)隐藏现有声明,而另一些则没有。具体来说,“按需导入”(例如 import java.util.*; 或 java.lang.* 的隐式导入)不会影响其他声明。
例如;
package foo;
import java.sql.Date;
import java.util.*; // import on demand: java.util.Date does not shadow java.sql.Date
import java.awt.*; // import on demand: java.awt.List does not shadow java.util.List
class Integer { // (foo.)Integer shadows java.lang.Integer
...
static class Integer { // (foo.Integer.)Integer shadows foo.Integer.
...
List t = ... // Compilation error, because there are currently two visible
// declarations of List (JLS 6.5.5.1)
}
}
另一个问题是“单一类型导入”(如上面的import java.sql.Date;)会影响在同一包中声明的类型以及按需导入的类型,但它不会影响通过另一个“单一类型”导入的其他类型类型导入”(JLS 6.3.1)。所以比如下面是编译错误:
import java.sql.Date;
import java.util.Date; // Compilation error
【讨论】:
它应该遵循与Scope of Local Variable Declarations 中显示的不同范围相同的顺序。
编辑:我的 JVM 规范链接指的是执行阶段,而不是编译阶段,正如 OP Gili 所评论的那样
由于它不是一个完整的答案,我将其保留为 CW 以启动线程。
【讨论】: