java foreach内部实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011870280/article/details/84374537

今天突然想看看foreach内部实现是怎样的,比如如下代码:

for (EmailClientEntity emailClient : emailClientDao.findAll()) {
//TODO something...
}

通过javap看看字节码指令:

  public void initAllEmailSession();
    Code:
       0: aload_0
       1: getfield      #9                  // Field emailClientDao:Lcom/xxx/unionloan/dao/EmailClientDao;
       4: invokeinterface #10,  1           // InterfaceMethod com/xxx/unionloan/dao/EmailClientDao.findAll:()Ljava/util/List;
       9: invokeinterface #11,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      14: astore_1

      15: aload_1
      16: invokeinterface #12,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z

      21: ifeq          98
      24: aload_1
      25: invokeinterface #13,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      30: checkcast     #14                 // class com/xxx/unionloan/entity/EmailClientEntity
      33: astore_2
      34: aload_0
      35: getfield      #8                  // Field storeMap:Ljava/util/Map;
      38: aload_2
      39: invokevirtual #15                 // Method com/xxx/unionloan/entity/EmailClientEntity.getEmailAddress:()Ljava/lang/String;
      42: new           #16                 // class java/util/Properties
      45: dup
      46: invokespecial #17                 // Method java/util/Properties."<init>":()V
      49: aconst_null
      50: invokestatic  #18                 // Method javax/mail/Session.getDefaultInstance:(Ljava/util/Properties;Ljavax/mail/Authenticator;)Ljavax/mail/Session;
      53: ldc           #19                 // String imap
      55: invokevirtual #20                 // Method javax/mail/Session.getStore:(Ljava/lang/String;)Ljavax/mail/Store;
      58: invokeinterface #21,  3           // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      63: pop
      64: aload_0
      65: getfield      #8                  // Field storeMap:Ljava/util/Map;
      68: aload_2
      69: invokevirtual #15                 // Method com/xxx/unionloan/entity/EmailClientEntity.getEmailAddress:()Ljava/lang/String;
      72: invokeinterface #22,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
      77: checkcast     #23                 // class javax/mail/Store
      80: aload_2
      81: invokevirtual #24                 // Method com/xxx/unionloan/entity/EmailClientEntity.getSmtpHost:()Ljava/lang/String;
      84: aload_2
      85: invokevirtual #15                 // Method com/xxx/unionloan/entity/EmailClientEntity.getEmailAddress:()Ljava/lang/String;
      88: aload_2
      89: invokevirtual #25                 // Method com/xxx/unionloan/entity/EmailClientEntity.getEmailPassword:()Ljava/lang/String;
      92: invokevirtual #26                 // Method javax/mail/Store.connect:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
      95: goto          15
      98: goto          113
     101: astore_1
     102: getstatic     #28                 // Field log:Lorg/slf4j/Logger;
     105: ldc           #29                 // String 数据库的邮箱配置不正确!
     107: aload_1
     108: invokeinterface #30,  3           // InterfaceMethod org/slf4j/Logger.error:(Ljava/lang/String;Ljava/lang/Throwable;)V
     113: return
    Exception table:
       from    to  target type
           0    98   101   Class java/lang/Exception

可以看到标红部分的意思:

第1个引用型变量进栈

获取对象的字段emailClientDao,将其值压入栈顶

调用接口方法EmailClientDao.findAll:()保存到第2局部变量

调用接口方法的List.iterator:()保存第2局部变量

栈顶引用对象存入第2局部变量

第2个引用型变量进栈

调用接口方法Iterator.hasNext()保存结果到第二局部变量

看出来foreach的内部实现是获取集合的迭代器来实现的。

猜你喜欢

转载自blog.csdn.net/u011870280/article/details/84374537
今日推荐