内部静态类和非内部静态类的区别

发布于:2025-03-04 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

问题:

原理:

外部类与非内部静态类

外部类与静态内部类

加载顺序

总结:

1.非静态内部类依赖于外部类的实例,而静态内部类不依赖于外部类的实例。

2.非静态内部类可以访问外部类的实例变量和方法,而静态内部类只能访问外部类的静态成员。

3.非静态内部类不能定义静态成员,而静态内部类可以定义静态成员。

4.非静态内部类在外部类实例化后才能实例化,而静态内部类可以独立实例化。

5.非静态内部类可以访问外部类的私有成员,而静态内部类不能直接访问外部类的私有成员,需要通过实例化外部类来访问。


问题:

刷完面经,以写博客输出的方式加深面经理解,特此记录。

原理:

从内存的角度更能理解的透彻一些

外部类与非内部静态类

  •  非内部静态类实例和外部静态类实例是两个独立的对象,它们分别在堆内存中分配空间。
  • 但是,非内部静态类实例隐式持有一个指向外部实例的引用(也就是指针或者说是地址),这个引用是编译器自动生成的。
  • 非内部静态类有了外部类的this,那当然可以访问外部类的实例变量,
  • 当然也可也访问静态变量,这里要特别注意,即使没有外部类的this,也可也通过类名访问。

外部类与静态内部类

  • 外部类与静态内部类,二者之间没啥关系,可以相互独立存在。
  • 只是,语法上我们把它俩放在了一块。只是逻辑上的内部与外部,这里一定要理解清楚。
  • 说白了,外部类与非内部静态类,是真的存在内外的关系,
  • 而外部类与静态内部类,只是把一个静态类放在了一个类里面,因为有非内部静态类这样的称呼,所以我们也就把(一个静态类放在了一个类里面)这样的情况叫做 静态内部类
  • 它的生命周期独立于外部类实例。

加载顺序

  • 先加载外部类,后加载内部类,因为内部类必须得拿到外部类的引用才行。
  • 静态内部类和外部类二者独立,谁被用到,谁就被加载。

总结:

如果你理解了上面从内存角度的问题,那么接下来这些案例,你都可以从这个角度想通了。

1.非静态内部类依赖于外部类的实例,而静态内部类不依赖于外部类的实例。

原因:

只有外部类实例化后,非内部静态类才能拿到内部类的引用,而静态内部类和外部类二者独立,所以不需要进行实例化后才能拿到引用。

class OuterClass {
    private String outerField = "Outer Field";

    class NonStaticInnerClass {
        void display() {
            System.out.println(outerField); // 可以直接访问外部类的实例变量
        }
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.NonStaticInnerClass inner = outer.new NonStaticInnerClass();
        inner.display(); // 输出:Outer Field
    }
}


class OuterClass {
    private static String staticOuterField = "Static Outer Field";

    static class StaticInnerClass {
        void display() {
            System.out.println(staticOuterField); // 可以访问外部类的静态成员
        }
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
        staticInner.display(); // 输出:Static Outer Field
    }
}

2.非静态内部类可以访问外部类的实例变量和方法,而静态内部类只能访问外部类的静态成员。

原因:内存区域不一样,而且非静态内部类有外部类的引用,静态内部类与外部类独立,静态内部类单独存储在别的区域。

class OuterClass {
    private String outerField = "Outer Field";

    class NonStaticInnerClass {
        void display() {
            System.out.println(outerField); // 可以访问外部类的私有实例变量
        }
    }
}

class OuterClass {
    private String outerField = "Outer Field";
    private static String staticOuterField = "Static Outer Field";

    static class StaticInnerClass {
        void display() {
            // System.out.println(outerField); // 编译错误:无法访问实例成员
            System.out.println(staticOuterField); // 可以访问静态成员

            // 如果需要访问实例成员,必须通过外部类实例
            OuterClass outer = new OuterClass();
            System.out.println(outer.outerField);
        }
    }
}

3.非静态内部类不能定义静态成员,而静态内部类可以定义静态成员。

原因:静态成员需要在类加载时就存在,并且不依赖于任何实例,但是非静态内部类需要在外部类加载后才可以,所以不行。

如果你问我为什么不解释静态内部为甚可以定义静态成员,你白看了兄弟!。

class OuterClass {
    class NonStaticInnerClass {
        // static int staticField = 10; // 编译错误:非静态内部类不能定义静态成员
        // static void staticMethod() {} // 编译错误
    }
}

class OuterClass {
    static class StaticInnerClass {
        static int staticField = 10; // 允许定义静态成员
        static void staticMethod() {
            System.out.println("This is a static method.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(OuterClass.StaticInnerClass.staticField); // 输出:10
        OuterClass.StaticInnerClass.staticMethod(); // 输出:This is a static method.
    }
}

4.非静态内部类在外部类实例化后才能实例化,而静态内部类可以独立实例化。

前面都解释过了,略。

class OuterClass {
    class NonStaticInnerClass {}
}

public class Main {
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.NonStaticInnerClass inner = outer.new NonStaticInnerClass();
    }
}



class OuterClass {
    static class StaticInnerClass {}
}

public class Main {
    public static void main(String[] args) {
        OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
    }
}

5.非静态内部类可以访问外部类的私有成员,而静态内部类不能直接访问外部类的私有成员,需要通过实例化外部类来访问。

class OuterClass {
    private String privateField = "Private Field";

    class NonStaticInnerClass {
        void display() {
            System.out.println(privateField); // 可以访问外部类的私有成员
        }
    }
}

class OuterClass {
    private String privateField = "Private Field";

    static class StaticInnerClass {
        void display() {
            // System.out.println(privateField); // 编译错误:无法直接访问私有成员
            OuterClass outer = new OuterClass();
            System.out.println(outer.privateField); // 通过实例访问
        }
    }
}