【问题标题】:Java identifier resolution rulesJava 标识符解析规则
【发布时间】:2009-12-30 10:19:01
【问题描述】:

Java 编译器使用什么搜索顺序来解析以下类中的Foo

class Test
{
  Foo f;
}

实证检验显示以下搜索顺序:

  1. 嵌套类
  2. 超类嵌套类
  3. java.lang.* 类
  4. 其他?

但我想知道Java Language Specification 中讨论的位置。

【问题讨论】:

    标签: java compiler-construction


    【解决方案1】:

    我认为没有您所说的搜索顺序。相反,我认为这条规则适用:

    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
    

    【讨论】:

      【解决方案2】:

      它应该遵循与Scope of Local Variable Declarations 中显示的不同范围相同的顺序。

      编辑:我的 JVM 规范链接指的是执行阶段,而不是编译阶段,正如 OP Gili 所评论的那样

      由于它不是一个完整的答案,我将其保留为 CW 以启动线程。

      【讨论】:

      • -1,一旦类已经被编译,您的链接“从类文件表示派生类”与加载时分辨率有关。我问的是编译器如何解析标识符。您指向“局部变量声明范围”的链接指向错误的部分,并且无论如何都没有讨论解决顺序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多