今天写代码的时候,需要遍历一个作为参数传递进来的容器,

当时顺手就加上了判空条件:

if(null==list)return;

后来就像,不知道遍历(foreach)有没有帮我做这个工作:

下面看实验结果:

public static void main(String[] args) {
List<String> list =null;
for (String s:list){
System.out.println(s);
}
}

运行时报空指针错误:

Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:37)

说明在进行foreach遍历的时候,需要判空的。

下面看看foreach到底是怎么实现的:

foreach是在jdk 1.5版本后推出更优雅的遍历写法:

jdk1.5之前:

遍历数组:

  for (int i=0;i<array.length;i++){
//do something
}

遍历容器:

while (list.iterator().hasNext()){
//do something
}

jdk1.5之后:

 for (String s:list){
//do something
}

代码看起来优雅了许多。

那foreach是一个新的东西么?相对于以前的的for循环来说,到底哪个效率要高一些呢?

下面看测试代码:

    List<String> list = new ArrayList<>();
String[] test = new String[]{}; //遍历容器测试
public void collectionForeachTest() {
for (String s : list) {
//do something
}
} //循环容器测试
public void collectionIteatorTest() {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
//do something
}
} //遍历数组测试
public void arrayForeachTest() {
for (String s : test) {
//do something
}
} //循环数组测试
public void indexTest() {
for (int i = 0; i < test.length; i++) {
//do something
}
}

首先编译。javap -c Test.class查看编译源文件:

容器:使用遍历和迭代器:

public void collectionForeachTest();
Code:
0: aload_0
1: getfield #4 // Field list:Ljava/util/List;
4: invokeinterface #7, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
9: astore_1
10: aload_1
11: invokeinterface #8, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
16: ifeq 32
19: aload_1
20: invokeinterface #9, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
25: checkcast #5 // class java/lang/String
28: astore_2
29: goto 10
32: return public void collectionIteatorTest();
Code:
0: aload_0
1: getfield #4 // Field list:Ljava/util/List;
4: invokeinterface #7, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
9: astore_1
10: aload_1
11: invokeinterface #8, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
16: ifeq 22
19: goto 10
22: return

数组:遍历和索引:

 public void arrayForeachTest();
Code:
0: aload_0
1: getfield #6 // Field test:[Ljava/lang/String;
4: astore_1
5: aload_1
6: arraylength
7: istore_2
8: iconst_0
9: istore_3
10: iload_3
11: iload_2
12: if_icmpge 26
15: aload_1
16: iload_3
17: aaload
18: astore 4
20: iinc 3, 1
23: goto 10
26: return public void indexTest();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: aload_0
4: getfield #6 // Field test:[Ljava/lang/String;
7: arraylength
8: if_icmpge 17
11: iinc 1, 1
14: goto 2
17: return

可以看出来,总体来说:foreach就是iterator的语法糖,使用foreach,最后都会编译成传统的Iterator的方法。

结论:

1.使用foreach需要检查对象是否为空,因为使用foreach相当于使用了obj.itreator()

2.foreach只是一个语法糖,使用foreach更安全(不会带来数组越界的错误),但是最终编译结果和以前的写法是一样的。

使用foreach需要判空。的更多相关文章

  1. mybatis xml的无效判空

    <insert id="insert"> <if test="xxxMappingEntityList != null and xxxMappingEn ...

  2. Java使用Optional与Stream来取代if判空逻辑(JDK8以上)

    Java使用Optional与Stream来取代if判空逻辑(JDK8以上) 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作. 注:如 ...

  3. java中判空

    一.概述 java中判等似乎很简单,==用来判断对象引用(内存地址)是否相同,equals用来判断值是否相同.你可以试用String对象轻松区分这一点. 那么在null判等(也就是判空操作)时呢? 可 ...

  4. JSTL: empty 可以减少很多繁冗的判空(转)

    ${empty student.name }Empty是判空为空返回的真不为空返回的是假 ${(empty student.name)? '空' : '非空'} <c:if test=" ...

  5. StringUtils工具类常用方法汇总1(判空、转换、移除、替换、反转)

      Apache commons lang3包下的StringUtils工具类中封装了一些字符串操作的方法,非常实用,使用起来也非常方便.最近自己也经常在项目中使用到了里面的一些方法,在这里将常用的方 ...

  6. 运算符关键字。数据区别大小写。日期范围。判空的两种写法。NOT IN的两种写法。IN范围可含NULL,但NOT IN值范围不能含NULL。

    比较:>,<,=,>=,<=,<>(!=) 逻辑:AND,OR,NOT 范围:BETWEEN...AND... 范围:IN,NOT IN 判空:IS NULL, I ...

  7. jquery判空 string类型的日期比较大小

    jquery 判空 if(value.length<=0){  alert("kongzhi"); } jquery string类型的日期比较大小 var startTim ...

  8. jeecg中excel导出字段判空处理

    我们清楚,jeecg 导出 excel 采用的是 easypoi,不知道是否遇到过这种情况: 我们以一个实体属性为例: @Excel(name="问题分类",dicCode=&qu ...

  9. StringUtils工具类常用方法汇总(判空、转换、移除、替换、反转)

    Apache commons lang3包下的StringUtils工具类中封装了一些字符串操作的方法,非常实用,使用起来也非常方便.最近自己也经常在项目中使用到了里面的一些方法,在这里将常用的方法总 ...

随机推荐

  1. python3 常用模块

    一.time与datetime模块 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们 ...

  2. 用Vue.js开发微信小程序:开源框架mpvue解析

    前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...

  3. Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。

    Error creating document instance. Cause: org.xml.sax.SAXParseException;  lineNumber: 1; columnNumber ...

  4. springboot字符集乱码

    入门扫盲:https://www.2cto.com/database/201701/584442.html 1.修改springweb类bug 2.数据库连接配置 3.数据库字符集 https://w ...

  5. iot:下一步要做的工作

    1.DeviceMessage抽象(定义&支持扩展)2.createDeviceMessage.analyseDeviceMessage(支持扩展)3.日志打印4.错误处理5.断线重连6.交互 ...

  6. OAuth2.0学习(1-7)授权方式4-客户端模式(Client Credentials Grant)

    授权方式4-客户端模式(Client Credentials Grant) 客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提 ...

  7. IPv6原理、应用与实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯微信技术架构部团队 2017年11月26日,中共中央办公厅和国务院办公厅印发了<推荐互联网协议第六版(IPv6)规模部署行动 ...

  8. Codeforces Round #436 (Div. 2) B. Polycarp and Letters

    http://codeforces.com/contest/864/problem/B 题意: 给出一个字符串,要求找到一个集合S,使得从S中选出的所有数,在这些数的位置上的字母全部为小写且是不同的字 ...

  9. Hive:动静态分区

    http://hugh-wangp.iteye.com/blog/1612268 http://blog.csdn.net/opensure/article/details/46537969 使用静态 ...

  10. hdu2674 N!Again---思维

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2674 题目大意: 求n!%2009的值 思路: 由于模2009,所以大于等于2009的直接为0,前2 ...