内部类和静态嵌套类

术语规范:按照官方文档,定义在外部类(封装类)内部的类称之为nested class,根据是否被static关键字修饰又分为两类:static nested classes 和 inner classes。闭包

class OuterClass {

    static class StaticNestedClass {}
    class InnerClass {}
}

使用嵌套类的好处在于:this

  • 当某个类为旁类专用时,将其写成嵌套类能使得代码结构更紧凑。指针

  • 嵌套类增长了封装性code

内部类和静态嵌套类的不一样根源来自于static,最大区别在于访问外部类成员的权限。对象

1.静态嵌套类

static修饰符使得嵌套类对象成为外部类的静态成员,与外部类直接关联。作用域

这样静态嵌套类做为一个静态成员,仅能访问外部类的静态成员,由于外部类中的非静态成员与外部类对象相关,静态嵌套类就不能访问他们,这使得静态嵌套类的功能变的很弱,可用之处不多。文档

另外由于静态嵌套类是依附于外部类而非外部类对象的,因此不一样的外部类对象共享一个静态嵌套类,这一点与内部类不一样,能够用来包装main方法。class

静态嵌套类的声明示例:变量

OuterClass.StaticNestedClass nestedObject =
     new OuterClass.StaticNestedClass();

2.内部类

没有static修饰意味着一个内部类是和外部类对象关联的,也能够说一个内部类对象存在于外部类对象中,是外部类对象的一个成员,所以内部类对象能够访问外部类对象的所有成员,包括私有成员。原理

  • 由于内部类依赖于外部类对象而存在,因此不能定义任何静态成员。

  • 内部类对象能够访问外部类的全部成员变量,包括私有成员,这是Java闭包的原理;

  • 由于内部类隐含对外部类的引用,因此外部类就不能被JVM的垃圾回收机制自动垃圾回收。

  • 不一样的外部类对象之间没有公共的内部类对象成员。

内部类的声明示例:

OuterClass.InnerClass innerObject = new OuterObject().new InnerClass();

3.变量遮蔽Shadowing

嵌套类和封装类以及局部方法区的变量做用域有重叠,若是有同名变量将发生变量遮蔽。

public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

注意这里对3种不一样变量的引用方式,结果以下

x = 23                  //1.  局部变量
this.x = 1              //2.内部类变量
ShadowTest.this.x = 0   //3.外部类变量

内部类中this指针指向内部类本身,ShadowTest.this则指向外部类对象;

不加修饰的变量,将执行就近匹配原则;若是名称相同将发生变量遮蔽效应;为了防止隐患,内部类引用外部类对象时应使用第三种方法。

相关文章
相关标签/搜索