【Java基础面试题】内部类有单独的.class文件吗

75 阅读1分钟

内部类一般有两种,成员内部类和匿名内部类,运行后都会有单独的.class文件产生;

1.成员内部类

  • 成员内部类,一般指类中再嵌套一个类,称为外部类和内部类;
  • 内部类只能服务于外部类,只能在外部类中实例化;
  • 内部类可以调用外部类的成员变量和方法,即使是私有的;
    • 此时系统自动补充了外部类.this.变量的操作
//Mom.java
package com.ott.autotest;

public class Mom {
    private int a = 4;

    public void sayHi(){
        System.out.println("外部类方法sayHi()");
    }

    public void handleInner(){
        Child c = new Child();
        c.print();
    }

    public class Child {
        public void print(){
            System.out.println(a);
            sayHi();
        }
    }
}
//Test.java
package com.ott.autotest;

public class Test {
    public static void main(String[] args) {
        Mom m = new Mom();
        m.handleInner();
    }
}

//4
//外部类方法sayHi()
  • 此时执行后,会出现三个.class文件
    • Mom.class
    • Mom$Child.class (成员内部类单独字节码文件)
    • Test.class

image.png

2.匿名内部类

  • 匿名内部类一般是服务于adstract抽象方法的;
  • 当抽象类只使用一次时,可用匿名内部类的方式自动创建派生类及重写抽象方法;
  • 匿名内部类也是会产生自己的.class文件的
    • 所以此时外部类的变量默认是final形式不可在内部类修改的
    • 因为有单独的.class文件,在内部类修改也是修改的变量的副本,所以为了数据的安全性和可预测性,Java要求在匿名内部类中引用的局部变量必须声明为final或effectively final;
//Aoo.java
package com.autotest.test2;

public abstract class Aoo {
   public abstract void show();
}
//Test.java
package com.autotest.test2;

public class Test {
    public static void main(String[] args) {
        int c = 34;
        Aoo a = new Aoo() {
            @Override
            public void show() {
                System.out.println("匿名内部类");
                System.out.println(c);
                //c = 66;
                //Variable 'c' is accessed from within inner class, needs to be final or effectively final
            }
        };
        a.show();
    }
}

//匿名内部类
//34
  • 此时执行结束后,会有三个.class文件出现;
    • Test.class
    • Aoo.class
    • Test$1.class (匿名内部类单独的字节码文件)

image.png