Java 内部类详解

本文详细介绍了Java中的内部类,包括静态内部类、成员内部类、方法内部类和匿名内部类。阐述了它们的访问权限、调用方式以及适用场景。例如,静态内部类适用于不依赖外部类实例的情况,成员内部类则高度依赖外部类实例,方法内部类有短暂生命周期,而匿名内部类常用于简洁代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、分类

内部类分为以下两种:

  • 静态内部类
  • 非静态内部类

非静态内部类又分为以下三种:

  • 成员内部类
  • 方法内部类
  • 匿名内部类

二、静态内部类

测试代码如下:

public class Outer {
    private String a = "a";
    private static String b = "b";
    public String c = "c";
    public static String d = "d";
    private static String e = "e";

    private void method1() {
        System.out.println("method1");
    }

    private static void method2() {
        System.out.println("method2");
    }

    public static class Inner {
        private static int e = 5;

        public static void sayHello() {
            // 静态内部类只可以直接访问静态资源,所以编译报错
            // System.out.println(a);
            System.out.println(new Outer().a);
            System.out.println(b);
            // 静态内部类只可以直接访问静态资源,所以编译报错
            // System.out.println(c);
            System.out.println(new Outer().c);
            System.out.println(d);
            // 静态内部类只可以直接访问静态资源,所以编译报错
            // method1();
            new Outer().method1();
            method2();
            // 静态内部类定义和外部类同名的变量时,会使用在静态内部类中定义的变量
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        new Outer.Inner().sayHello();
        new Inner().sayHello();
        // 调用静态内部类的静态方法可以这样用
        Inner.sayHello();
    }
}

控制台输出如下:

a
b
c
d
method1
method2
5

结论:

  1. 静态内部类的调用方法:new Outer.Inner().sayHello()new Inner().sayHello()Inner.sayHello()
  2. 静态内部类能直接访问到外部类的静态资源,但不可以直接访问外部类的非静态资源(可以借助外部类的实例对象访问)。
  3. 静态内部类定义和外部类同名的变量时,当使用时会调用在静态内部类中定义的变量。

使用场景:和外部类联系紧密,但是并不依赖于外部类实例的情况下,可以考虑使用静态内部类。

三、非静态内部类

1. 成员内部类

测试代码如下:

public class Outer {
    private String a = "a";
    private static String b = "b";
    public String c = "c";
    public static String d = "d";
    private static String e = "e";

    private void method1() {
        System.out.println("method1");
    }

    private static void method2() {
        System.out.println("method2");
    }

    // 非静态内部类可以使用外部类的所有静态和非静态资源,但不可以自己定义静态资源(包括静态变量、静态方法和静态代码块)
    public class Inner {
        // 报错,因为成员内部类不能定义静态变量
        // private static int e = 5;
        private int e = 5;
		
        // 该方法不可以用静态变量修饰
        public void sayHello() {
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
            System.out.println(d);
            method1();
            method2();
            // 内部类定义和外部类同名的变量时,会使用在内部类中定义的变量
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        new Outer().new Inner().sayHello();
    }
}

控制台输出如下:

a
b
c
d
method1
method2
5

结论:

  1. 成员内部类的调用方法:new Outer().new Inner().sayHello()
  2. 成员内部类可以直接访问外部类的静态资源和非静态资源。
  3. 内部类定义和外部类同名的变量时,会使用在内部类中定义的变量。

使用场景:和外部类联系密切,并且高度依赖外部类实例的情况下,定义一个成员内部类是不错的选择。

2. 方法内部类

测试代码如下:

public class Outer {
    private String name = "itming";

    public void sayHello() {
        class Inner {
            public void showName() {
                System.out.println("My name is " + name);
            }
        }
        new Inner().showName();
    }

    public static void main(String[] args) {
        new Outer().sayHello();
    }
}

控制台输出如下:

My name is itming

结论:

  1. 方法内部类的生命周期不超过包含它的方法的生命周期,因此,方法内部类只能在方法中使用。
  2. 由于方法内部类只能在包含它的方法内部使用,所以访问修饰符没有任何意义,于是 Java 直接禁止对方法内部类使用访问修饰符,如果使用的话会编译报错。

使用场景:一般只在需要高度封装的时候才会将类定义成方法内部类。

3. 匿名内部类

测试代码如下:

public class Outer {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("Hello Thread!");
                }
            }
        }.start();
        new Thread(() -> {
            for (int i = 0; i < 3; i++) {
                System.out.println("Hello Lambda!");
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("Hello Runnable!");
                }
            }
        }).start();
    }
}

控制台输出如下:

Hello Thread!
Hello Thread!
Hello Thread!
Hello Lambda!
Hello Lambda!
Hello Lambda!
Hello Runnable!
Hello Runnable!
Hello Runnable!

使用场景:对代码简洁度有要求的情况下首选匿名内部类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值