Java 嵌套类

顾名思义,定义在一个类中的类,如下:

class OuterClass {
    ...
    class NestedClass {
        ...
    }
}

分为两种:静态、非静态。

被声明为静态的嵌套类称作_静态嵌套类_,非静态嵌套类称作_内部类_。如下:

class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}

内部类可以访问外部类的成员(即使被声明为私有),而静态嵌套类则不可以。嵌套类是外部类的成员,可以被声明为公有、私有、受保护和包私有四种访问级别。

那为什么用嵌套类呢?

静态嵌套类

与类成员一样,静态嵌套类与其外部类相关联,像静态方法一样,静态嵌套类不可引用其外部类的实例成员。实际上,静态嵌套类在行为上是顶层类,只不过为了打包便利,才把它内嵌到另一个顶层类中。

要创建静态嵌套类对象,如下:

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

内部类

与实例成员一样,内部类与其外部类的实例相关联,可直接访问其外部类的对象的属性和方法,但是其内不可定义静态成员。

为了实例化内部类,必须先实例化外部类,然后用外部类对象创建内部类对象,如下:

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

嵌套中同名遮蔽问题

如下:

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);
    }
}

输出:

x = 23
this.x = 1
ShadowTest.this.x = 0

局部和匿名类

还有另外两种内部类:在一个方法体里面定义一个内部类,被称作局部类;同样在方法体内定义一个内部类,并且没有命名,被称作匿名类

Lambda表达式

匿名类有这样一个问题:当它的实现非常简单时,例如为只有一个方法的接口,这时它的语法看起会显得笨重、不清楚。在这种情况下,经常是试图把一个函数作为参数传给另一个方法,Lambda表达式能很好解决这个问题。

方法引用

有些时候,Lambda表达式只是调用一个已经存在的方法,如果能通过一个名字就指向这个方法的话,会显得更加清晰。方法引用可以实现这个,在调用方法时,它就是紧凑、易于阅读的Lambda表达式。

参考链接

https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html. https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html