定义在DTO或VO类中,可以在外面访问的内部类
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | 
 
  @Data public class BusinessOutDTO {
      private Integer id;     private String name;     private List<BusinessDetailOutDTO> businessDetailList;
      
 
      @Data     public class BusinessDetailOutDTO {         private Integer id;         private String detailName;     } }
 
  | 
 
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   |  BusinessOutDTO businessOutDTO = new BusinessOutDTO(); businessOutDTO.setId(1); businessOutDTO.setName("business-A");
  BusinessOutDTO.BusinessDetailOutDTO businessDetailOutDTO = new BusinessOutDTO().new BusinessDetailOutDTO(); businessDetailOutDTO.setId(1); businessDetailOutDTO.setDetailName("businessDetail-a");
  List<BusinessOutDTO.BusinessDetailOutDTO> businessDetailList = new ArrayList<>(); businessDetailList.add(businessDetailOutDTO); businessOutDTO.setBusinessDetailList(businessDetailList); System.out.println(businessOutDTO);
 
 
 
  List<BusinessOutDTO.BusinessDetailOutDTO> businessDetailList1 = businessOutDTO.getBusinessDetailList(); System.out.println(businessDetailList1);
 
 
  | 
 
特点:
- 声明为 public,非 static,属于成员内部类
 
- 定义成内部类只是觉得它“属于”其外部类,其实把它定义成独立的非内部类也是可以的
 
- 因为外部类和内部类都是 DTO 类,无逻辑,所以只有外部类创建和使用到内部类,内部类不会访问外部类属性
 
在外部类中被用来做逻辑处理的内部类
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | public class DeadlineUtil {
      public static DeadlineBO add(int deadlineVal1, String deadlineUnit1, int deadlineVal2, String deadlineUnit2) {         DeadlineBO deadlineBO1 = new DeadlineUtil.DeadlineBO(deadlineVal1, deadlineUnit1);          DeadlineBO deadlineBO2 = new DeadlineUtil.DeadlineBO(deadlineVal2, deadlineUnit2);
          System.out.println("==============此处是一段期限相加逻辑==============");         DeadlineBO deadlineBOResult = new DeadlineUtil.DeadlineBO(0, "year");         return deadlineBOResult;     }
      @Data     public static class DeadlineBO {         private int deadlineVal;         private String deadlineUnit;
          public DeadlineBO(int deadlineVal, String deadlineUnit) {             this.deadlineVal = deadlineVal;             this.deadlineUnit = deadlineUnit;         }     } }
  | 
 
内部类 DeadlineBO 被用来做逻辑处理,并作为方法的返回类型,注意其在外部类方法 add 方法的返回类型声明中,不用加外部类名前缀”DeadlineUtil.”。
使用示例:
1
   | DeadlineUtil.DeadlineBO addResult = DeadlineUtil.add(1, "year", 3, "month");
   | 
 
在外面使用时,还是会加外部类名前缀”DeadlineUtil.”。
另外,这个内部类被声明为“静态内部类”,静态内部类的特点是不需要 new 外部类对象就能使用,但也不能访问外部类的非静态成员。对于工具类而言,因为不希望创建工具类的对象,所以用静态内部类更合适。
如果没有声明为静态内部类(即没有static的内部类),那么上面的 add 方法会是这样:
1 2 3 4 5 6 7 8
   | public static DeadlineBO add(int deadlineVal1, String deadlineUnit1, int deadlineVal2, String deadlineUnit2) { 	DeadlineBO deadlineBO1 = new DeadlineUtil().new DeadlineBO(deadlineVal1, deadlineUnit1);  	DeadlineBO deadlineBO2 = new DeadlineUtil().new DeadlineBO(deadlineVal2, deadlineUnit2);
  	System.out.println("==============此处是一段期限相加逻辑=============="); 	DeadlineBO deadlineBOResult = new DeadlineUtil().new DeadlineBO(0, "year"); 	return deadlineBOResult; }
  | 
 
特点:
- 声明为 public static,属于静态内部类
 
- 外部类会使用内部类作逻辑处理,所以外部类内部会创建和使用内部类对象,但内部类不会访问外部类属性
 
匿名内部类
创建匿名内部类之前,这个匿名内部类必须是继承自一个接口或抽象类。
常见的例子如创建线程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | public class MainTest {     public static void main(String[] args) {         Runnable runnable = newRunnable();         new Thread(runnable).start();     }
      public static Runnable newRunnable() {         return new Runnable() {             @Override             public void run() {                 System.out.println(Thread.currentThread().getName());              }         };     } }
  | 
 
Runnable 就是一个接口,Debug看newRunnable()方法返回的类型,会看到类似于”MainTest$1@555”字样,而上一个例子 DeadlineUtil.add() 方法返回的会是”DeadlineUtil$DeadlineBO”字样,区别就是”$”符号后面有没有具体的类名。而这个叫”MainTest$1@555”的对象就是外部类 MainTest 创建的“实现 Runnable 接口的匿名内部类”的对象。
如果不用这个匿名内部类,那么常规方法是:1)声明一个类实现 Runnable 接口及其 run 方法;2)在 MainTest 中创建1中声明的类的对象,使用这个对象
静态、非静态方法返回的匿名内部类
匿名内部类 作为 return 参数时,它所在的方法是 static 和非 static 的性质是不同的。
例如以下代码中两个方法都返回 Runnable 接口的匿名内部类对象,但一个是 static 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public class RunnableLoader {
      public Runnable noStaticRunnable() {         return new Runnable() {             @Override             public void run() {                 System.out.println(Thread.currentThread().getName());             }         };     }
      public static Runnable staticRunnable() {         return new Runnable() {             @Override             public void run() {                 System.out.println(Thread.currentThread().getName());             }         };     } }
  | 
 
分别调用这两个方法返回不同的 Runnable 对象,Debug看时,发现非 static 方法返回的对象中有一个属性this$0指向其外部类对象RunnableLoader,而 static 方法返回的就没有这个对象。原因就是外部类的 static 方法不会创建外部类对象,也不能访问外部类对象实例。
Debug代码与截图如下:
1 2 3 4
   | RunnableLoader runnableLoader = new RunnableLoader(); Runnable runnable = runnableLoader.noStaticRunnable();
  Runnable staticRunnable = RunnableLoader.staticRunnable();
   | 
 
使用到匿名内部类以外的变量
这里说的“匿名内部类以外的变量”是说,这个变量既不是匿名内部类中声明的,也不是外部类声明的,例如下面这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | public class EnumerationLoader {
      public Enumeration<String> getResource() {         Enumeration<String> e = this.get(); 
          return new Enumeration<String>() {             @Override             public boolean hasMoreElements() {                 return e.hasMoreElements();              }
              @Override             public String nextElement() {                 return e.nextElement();             }         };     } }
  | 
 
Debug这个方法返回的匿名内部类对象,截图:
可以看到,这个变量Enumeration<String> e和外部类对象this$0一样,也被认为是匿名内部类的属性之一。