Java内部类

概念分类
成员内部类:成员内部类是最普通的内部类,可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
局部内部类:局部内部类是定义在一个方法、构造器或代码块中的类。它只能在其定义的范围内使用,通常用于封装仅在该方法中需要的逻辑。
静态内部类:静态内部类不持有外部类的引用,可直接通过外部类名访问,不需要外部类的实例即可创建。
匿名内部类:匿名内部类通常用于单次使用的类,如事件监听器等场景。

访问权限
成员内部类:成员内部类可以访问外部类的所有成员,包括私有成员。
局部内部类:局部内部类只能访问外部类的final变量或者实际上不变的变量。(Java8以上可以,但是不推荐)
静态内部类:静态内部类无法访问外部类的非静态成员。
匿名内部类:匿名内部类通常用于重写某个或某些方法的场景。

实例化方式
成员内部类:成员内部类必须先实例化外部类,然后使用外部类的实例来实例化内部类。
局部内部类:局部内部类的对象的创建时机是在方法调用时,随方法执行完毕而销毁。
静态内部类:静态内部类可以直接实例化,无需外部类实例。
匿名内部类:匿名内部类在使用时直接通过new关键字后跟接口或类名进行实例化。

应用场景
成员内部类:成员内部类适用于与外部类关系紧密,共同完成特定功能的场景。
局部内部类:局部内部类适用于在特定方法内实现功能,且不希望在外部类其他部分可见的场景。
静态内部类:静态内部类适用于内部类的功能与外部类实例无关,只需访问静态成员的场景。
匿名内部类:匿名内部类适用于实现接口或继承类的场合,特别是只需要一次实现的情况。

成员内部类

public class scratch_7 {
    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        OutClass.InnerClass innerClass = outClass.new InnerClass();
        innerClass.printFields();
    }

}

class OutClass {

    private String outerField = "Outer Field";
    public static String outerStaticField = "Outer Static Field";

    // 成员内部类
    class InnerClass {

        private String innerField = "Inner Field";
//        public static String innerStaticField = "Inner Static Field";
        public final static String innerFinalField = "Inner Final Field";


        public void printFields() {
            System.out.println("Outer Field: " + outerField);
            System.out.println("Outer Static Field: " + outerStaticField);
            System.out.println("Inner Field: " + innerField);
            System.out.println("Inner Final Field: " + innerFinalField);
//            System.out.println("Inner Static Field: " + innerStaticField);
        }
    }
}

输出

Outer Field: Outer Field
Outer Static Field: Outer Static Field
Inner Field: Inner Field
Inner Final Field: Inner Final Field

innerStaticField是不被允许的:对于非静态内部类来说,它的存在依赖于外部类的实例。在创建外部类的实例之前,内部类本身并没有被加载到内存中,因此如果内部类中包含静态成员,就会出现矛盾:静态成员需要在外部类实例化后才能将内部类加载,但那时外部类还没有实例化,也就无法加载内部类。
innerFinalField是被允许的:如果将成员内部类中的静态变量声明为final,并且赋予一个编译时已知的常量值(如字面量),则编译不会出错。这是因为final static变量实际上是编译时常量,它们在编译时就被替换,不需要在运行时再进行初始化

局部内部类

public class scratch_7 {
    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        OutClass.InnerClass innerClass = outClass.new InnerClass();
        innerClass.printFields();
    }

}

class OutClass {

    private String outerField = "Outer Field";
    public static String outerStaticField = "Outer Static Field";

    // 成员内部类
    class InnerClass {

        private String innerField = "Inner Field";
        public final static String innerFinalField = "Inner Final Field";


        public void printFields() {
            int innerMethodField = 40;
            class InnerInnerClass {
                public void printFields() {
                    System.out.println("outerField: " + outerField);
                    System.out.println("outerStaticField: " + outerStaticField);
                    System.out.println("innerField: " + innerField);
                    System.out.println("innerFinalField: " + innerFinalField);
                    System.out.println("innerMethodField: " + innerMethodField);
                }
            }
            InnerInnerClass innerInnerClass = new InnerInnerClass();
            innerInnerClass.printFields();
        }
    }
}

结果

outerField: Outer Field
outerStaticField: Outer Static Field
innerField: Inner Field
innerFinalField: Inner Final Field
innerMethodField: 40

静态内部类

public class scratch_7 {
    public static void main(String[] args) {
        OutClass.InnerClass.printFields();
    }

}

class OutClass {

    public static String outerStaticField = "Outer Static Field";

    // 成员内部类
    static class InnerClass {

        public static String innerField = "Inner Final Field";
        public String innerField2 = "innerField2";

        public static void printFields() {
            int innerMethodField = 40;
            class InnerInnerClass {
                public void printFields() {
                    System.out.println("outerStaticField: " + outerStaticField);
                    System.out.println("innerFinalField: " + innerField);
                    System.out.println("innerMethodField: " + innerMethodField);
//                    System.out.println("innerMethodField: " + innerField2);
                }
            }
            InnerInnerClass innerInnerClass = new InnerInnerClass();
            innerInnerClass.printFields();
        }
    }
}

结果

outerStaticField: Outer Static Field
innerFinalField: Inner Final Field
innerMethodField: 40
Inner Final Field

匿名内部类

public class scratch_7 {
    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        outClass.printFields();
    }

}

class OutClass {

    public static String outerStaticField = "Outer Static Field";

    public void printFields() {
        InnerClass innerClass = new InnerClass() {
            @Override
            public void printFields() {
                System.out.println("printFields");
            }
        };
        innerClass.printFields();
    }

    interface InnerClass {
        void printFields();
    }
}

简化为使用lambda表达式

public class scratch_7 {
    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        outClass.printFields();
    }

}

class OutClass {

    public static String outerStaticField = "Outer Static Field";

    public void printFields() {
        Runnable runnable = () -> {
            System.out.println("printFields");
        };
        runnable.run();
    }
}

Runnable只能实现单一无返回值方法,如果需要返回值可以使用Callable

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值