为什么允许编译时常量在非静态内部类中变为静态?

时间:2016-05-29 13:25:42

标签: java static inner-classes

假设我们有以下代码。

public class Outer{
    class Inner{
        public static final String s = "abc";
    }
    static class Nested{
        public static final SomeOtherClass instance = new SomeOtherClass();
    }
} 

我理解实例化非静态内部类的对象需要外部类的对象static表示与类相关,为了访问它,不需要实例化对象。非静态内部类只能在我们实例化外部类的对象后才能使用。在其中包含任何静态引用可能没有意义。

我的问题:

  1. 非静态内部类可以在没有外部类的显式对象的情况下加载吗?

  2. 为什么编译时间常量(字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)允许在 static 中< strong>非静态内部课程?

  3. 编辑:为什么不允许非编译时间常量变为静态,我知道它是按照JLS,但只是想知道会出现什么问题,制定此规则的意图是什么。 / strong>

2 个答案:

答案 0 :(得分:4)

  
      
  1. 非静态内部类可以在没有任何外部类的显式对象的情况下加载吗?
  2.   

是。创建内部类的实例需要外部类的实例。但是在创建任何实例之前都可以加载这两个类。

  
      
  1. 为什么我们可以在非静态内部类中使编译时常量(字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)是静态的?
  2.   

语言规范允许常量变量的此异常。来自Java Language Specification, section 8.1.3: "Inner classes and enclosing instances"

  

如果内部类声明显式或隐式静态的成员,则该编译时错误,除非该成员是常量变量(§4.12.4)。

由于部分4.12.4, "final Variables"

,字符串变量可以是常量
  

常量变量是基本类型或类型String的最终变量,使用常量表达式初始化(​​第15.28节)。

答案 1 :(得分:0)

问题1 - 非静态内部类可以在没有任何外部类的显式对象的情况下加载吗?

是的,您可以通过这种方式加载非静态内部类,请看下面的示例:

class MyObject {
    class InnerObject {
        static final String prop = "SOME INNER VALUE";
    }

    static void doLoad() {
        System.out.println(InnerObject.prop);
    }
}

事情是没有太多理由这样做,因为非静态内部类不允许有任何静态块,方法,字段,如果这些不是最终的,如下面的问题。

问题2 - 为什么我们可以在非静态内部类中使编译时常量(字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)是静态的?

Java旨在让您可以在非静态内部类中使用staticfinal个字段。