内部类就是在一个类内部进行其他类结构的嵌套操作,这样设计的目的在于将某些特殊用途的类进行封装,比如B类只是给A类使用,那么我们将B类定义为A类的内部类,整体的代码逻辑就十分简洁。

内部类一样可以使用权限修饰符,publicprivateprotected都可以使用。

1. 普通内部类

普通内部类是无法在当前类以外的地方进行直接实例化,下面示例中在主函数程序中直接使用new Inner();是错误的,如果非要使用可以采用new Outter().new Inner();这样的方式:

  1. public class Outter {
  2. public Outter() {
  3. System.out.println("Outter");
  4. }
  5. public class Inner {
  6. public Inner() {
  7. System.out.println("Inner");
  8. }
  9. }
  10. public void printInner() {
  11. new Inner();
  12. }
  13. public static void main(String[] args) {
  14. new Outter();
  15. new Outter().printInner();
  16. }
  17. }

代码成功编译后,会产生两个文件 Outter$Inner.classOutter.class,可以明显地看出这是两个类文件,这也表明了不会在同一加载流程中:

  1. ls -la
  2. Outter$Inner.class Outter.class

2. 静态内部类

显然new Outter().new Inner();这样的调用方式太反人类了,我们期望使用方式类似new Outter.Inner();,这种调用格式与之前的静态方法很一致,称之为静态内部类

  1. public class Outter {
  2. public Outter() {
  3. System.out.println("Outter");
  4. }
  5. public static class Inner {
  6. public Inner() {
  7. System.out.println("Inner");
  8. }
  9. }
  10. public void printInner() {
  11. new Inner();
  12. }
  13. public static void main(String[] args) {
  14. new Outter.Inner();
  15. }
  16. }

💡 注意点 —————

  • 静态内部类只会在第一次实例化时才会加载一次,否则不会加载。
  • 类内部的属性和方法如果不加static的话,它就是属于实例对象的。

3. 匿名内部类

匿名内部类可以让代码更加简洁,我们可以在定义一个类时同时实例化。它与局部类很相似,不同的是它没有类名,如果某个局部类我们只使用一次,那么匿名内部类就非常适合使用。

匿名类是一个表达式,语法就类似于调用一个类的构造函数(new HelloWorld()),并包含了一个完善类定义的 代码块:

| ```java wolf.eat(new Animal() { @Override public void eat(Animal animal) { System.out.println(this.getName()

  1. + "likes eating " + animal.getName());
  2. }
  3. @Override
  4. public String getName() {
  5. return "sheep";
  6. }

});

  1. | ```java
  2. tigger.eat(new Wolf() {
  3. @Override
  4. public void eat(Animal animal) {
  5. super.eat(animal);
  6. }
  7. @Override
  8. public String getName() {
  9. return "wolf";
  10. }
  11. });

| | —- | —- |