静态内部类和非静态内部类

内部类是定义在另外一个类中的类,内部类可以声明 public、protected、private 等访问限制,可以声明为 abstract 的供其他内部类或外部类继承与扩展,或者声明为 static、final 的,也可以实现特定的接口。

静态内部类和非静态内部类最大的区别是:非静态内部类编译后隐式保存着外部类的引用(就算外部类对象没用了也GC不掉),但是静态内部类没有。

非静态内部类

我们直接先看来一个例子吧,在 Human 类里定义了一个 HumanLeg 非静态内部类,并且在 HumanLeg 类的实例方法中直接访问外部类的 private 访问权限的实例变量和类变量。

/**
 * 人类 - 外部类
 *
 * @author GrimMjx
 */
public class Human {

    private static final int eyes = 2;

    private static void count() {
        System.out.println("I can count number");
    }

    private int teeth = 10;

    private void say() {
        System.out.println("Hello world");
    }

    /**
     * 人腿 - 非静态内部类
     */
    public class HumanLeg {
        private Double length;

        public HumanLeg(Double length) {
            this.length = length;
        }

        public void test() {
            say();
            count();
            System.out.println("I have " + eyes + " eyes");
            System.out.println("I have " + teeth + " teeth");
            System.out.println("My leg has " + length.toString() + "cm long");
        }
    }

    public static void main(String[] args) {
        Human human = new Human();
        HumanLeg humanLeg = human.new HumanLeg(100D);
        humanLeg.test();
    }
}

运行结果:

Hello world
I can count number
I have 2 eyes
I have 10 teeth
My leg has 100.0cm long

创建非静态内部类的时候,必须先创建一个外部类;因为非静态内部类对象总有一个隐式引用,指向了创建它的外部类对象。

内部类的特殊语法规则

如果非静态内部类方法访问某个变量,其顺序为:

  • 该方法是否有该名字的成员变量 - 直接用该变量名
  • 内部类中是否有该名字的成员变量 - 使用this.变量名
  • 外部类中是否有该名字的成员变量 - 使用外部类的类名.this.变量名
/**
 * @author GrimMjx
 */
public class Outer {

    private int i = 1;

    public class Inner {
        private int i = 2;

        public void print() {
            int i = 3;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Outer.this.i);
        }
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.print();
    }
}

静态内部类

如果用 static 来修饰一个内部类,那么就是静态内部类,这个静态内部类是独立的,可以直接创建对象,因此:

  • 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。
  • 外部类可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象访问其实例成员。
/**
 * 静态内部类测试外部类。
 *
 * @author GrimMjx
 */
public class StaticInnerTest {
    private int x = 1;
    private static int y = 2;

    public void test(){
        System.out.println(new InnerClass().a);
        System.out.println(InnerClass.b);
    }

    static class InnerClass {
        private int a = 3;
        private static int b = 4;

        public void test(){
            //无法访问
//            System.out.println(x);
            System.out.println(y);
        }
    }

    public static void main(String[] args) {
        StaticInnerTest staticInnerTest = new StaticInnerTest();
        staticInnerTest.test();

        InnerClass innerClass = new InnerClass();
        innerClass.test();
    }
}

只要你坚持,一步一步来,总归会成功的。切忌,学技术急不来,快就是稳,稳就是快。技术有限,接收指正。如果您觉得写的可以,请点个推荐。

参考资料

内部类与静态内部类

posted @ 2022-06-20 23:28  不是很聪明  阅读(35)  评论(0)    收藏  举报