引用

https://www.cnblogs.com/dolphin0520/p/3811445.html

image.png

Inner Class内部类分为四种

  1. 成员内部类:定义为位于另一个类的内部
public class User {
    public static String name;
    private String age;

    public User (String name,String age){
        User.name=name;
        this.age=age;
    }

    class My{
        public void say(){
            System.out.println("my name is "+name);
            System.out.println("my age is "+age);
        }
    }
}

//使用
public static void main(String[] args) {
        User user=new User("FHC","22");
        User.My my= user.new My();
        my.say();
    }
  • 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员),但在内部类有与外部类相同的方法或属性时,访问外部类需要用外部类名.this.属性
  • 成员外部类访问内部类则比较麻烦,需要新建一个内部类才能通过实例访问(内部类没有静态方法)
  • 成员内部类依附外部类的存在而存在
  • 成员内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限
  1. 局部内部类:定义在一个方法或者一个作用域里面的类
public class User {
    public static String name;
    private String age;

    public User(String name, String age) {
        User.name = name;
        this.age = age;
    }

    public void say() {
        System.out.println("my name is " + name);
    }

    public User my() {
        class My extends User {
            public My(String name, String age) {
                super(name, age);
            }
        }
        return new My("FHC", "22");
    }
}

//使用
    public static void main(String[] args) {
        User user = new User("other", "21");
        User user1 = user.my();
        user1.say();
        System.out.println(user.getClass().equals(User.class));
        System.out.println(user1.getClass().equals(User.class));
    }
//输出
my name is FHC
true
false
  • 局部内部类不能有public、protected、private以及static修饰符的
  1. 匿名内部类:使用的时候去实现
public abstract class User {
    public abstract String my();
}
//使用
    public static void say(User user) {
        System.out.println("I am " + user.my());
    }

    public static void main(String[] args) {
        say(new User() {
            @Override
            public String my() {
                return "FHC";
            }
        });
    }
//输出
I am FHC
  • 匿名内部类是唯一 一种没有构造器的类
  1. 静态内部类:静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static
public class User {
    public static String name;
    private String age;

    public User (String name,String age){
        User.name=name;
        this.age=age;
    }

    static  class My{
        public void say(){
            System.out.println("my name is "+name);
        }
    }
}
//使用
public static void main(String[] args) {
        User.My my=new User.My();
        my.say();
    }
//输出
my name is null
  • 静态内部类只可以访问外部类的静态属性

内部类原理

  1. 为什么成员内部类可以无条件访问外部类的成员?
final com.cxh.test2.Outter this$0;
public com.cxh.test2.Outter$Inner(com.cxh.test2.Outter);
  • 通过反编译发现,内部类中保存了外部类的引用,且构造方法中编译器还是会默认添加一个参数,该参数的类型为指向外部类对象的一个引用。
  • 从这里也间接说明了成员内部类是依赖于外部类的,如果没有创建外部类的对象,则无法对Outter this&0引用进行初始化赋值,也就无法创建成员内部类的对象了。
  1. 为什么局部内部类和匿名内部类只能访问局部final变量?
  • 局部变量的值在编译期间就可以确定,则直接在匿名内部里面创建一个拷贝。如果局部变量的值无法在编译期间确定,则通过构造器传参的方式来对拷贝进行初始化赋值。
  • 故而,传入值并非真正的值,而仅仅是一个拷贝,内部类的变量改变不会对外部照成影响。表诉不一致,故而不可改变
    image.png