内部类、静态内部类

最近在阅读一些开源框架的源码,发现了static class这样的东西,似曾相识,可是又有点搞不清楚它确切的含义,今天把这个事情搞搞清楚。java

关于java当中的static,你们应该都有着必定的了解。多数时候使用它来修饰class当中的一个属性或者一个方法,这样的话,对这个属性或者方法的调用就能够不依赖于class的某一个实例了。框架

可是,若是用static来修饰一个内部class,它又表明着什么样的含义呢?看起来应该是跟修饰属性和方法表明着差很少的意思。spa

那么咱们还须要先复习一下非静态内部类的使用。对象

public class OutClass {
    private int value = 100;
    public class InnerClass {
        public void println(){
            System.out.println("I am an inner class!" + " the value of out obj is " + value);
        }
    }
}编译器

public class TestInner {
    public static void main(String[] args){
        OutClass.InnerClass innerObj = new OutClass().new InnerClass();
        innerObj.println();
    }
}源码

请注意一下,我标注成红色的部分,这里有几个知识点:编译

一、在InnerClass的定义当中,他是一个public的类,可是,即便如此,咱们在定义变量类型的时候,还必需要写上OutClass.InnerClass,这里,从逻辑上是说得通的,咱们须要知道这个内部类到底是来自哪里。由于咱们其实能够定义一个也叫InnerClass的顶层类,因此,若是不加上OutClass.,会让编译器无所适从的。class

二、在实例化内部类的时候,必须依赖于一个外部类的实例,这里和非static的属性和方法的使用是同样的,非static的内部类、属性、方法,都必须依赖于一个外部类的实例。变量

三、内部类当中能够随意访问外部类的属性和方法,关于这个问题,咱们能够这么理解,在构造内部类的时候,java编译器,会把一个外部类对象交给内部类对象来使用,这一点其实和第二点是息息相关的。开源框架

下面咱们再看一下静态内部类的使用:

public class OutClass {
    public static class InnerClass {
        public void println(){
            System.out.println("I am an static inner class!");
        }
    }
}

public class TestInner {
    public static void main(String[] args){
        OutClass.InnerClass innerObj = new OutClass.InnerClass();
        innerObj.println();
    }
}

这一次,咱们把InnerClass变成了static的,那么在实例化的时候,就能够不依赖于OutClass的实例了,static的语义的一致性在这里获得了充分的体现。那么因为内部类的实例化,并不依赖于外部类的实例,因此,内部类也没法访问外部类的任何非静态的属性和方法。

那么还有最后一个问题,咱们知道,虽然咱们不依赖于实例,来访问类的静态属性和方法,可是用实例来访问,其实也是能够的。

可是,我仍是要经过外部类的实例,来建立一个内部类的实例,这样能够吗?

public class TestInner {
    public static void main(String[] args){
        OutClass outObj = new OutClass();
        OutClass.InnerClass innerObj = outObj.new InnerClass();
        innerObj.println();
    }
}

红色的部分会报错,而给出的错误信息是:Qualified new a static class(有资格来new一个静态类),大概意思是,你能直接new一个静态内部类,就别经过外部类的实例了。

这里实际上是咱们今天的结论,static的语义,在用于class的时候,和它用于属性和方法的时候,语义是大致上相同的。惟一的不一样点,static在用于class的时候,是没法经过外部类实例来new一个静态内部类的。到底是基于什么样的考虑,有了这样的限制,暂时不知道~~~

相关文章
相关标签/搜索