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

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

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. Python内置函数(29)——slice

    英文文档: class slice(stop) class slice(start, stop[, step]) Return a slice object representing the set ...

  2. js new到底干了什么,new的意义是什么?

    学过JS的都知道 创建对象可以这样 var obj=new Object(); var obj=new Function(); 用内置的函数对象来构造对象 还可以这样自定义函数 function te ...

  3. Python基础题

    1. 执行Python脚本的两种方式: Chmod +x 脚本 ./脚本(路径的方式) Python 脚本 2. 简述位.字节的关系 一个字节=8位 3. 简述ASCII.unicode.utf-8/ ...

  4. Django Form组件 学生管理系统

    from django.db import models # Create your models here. class Classes(models.Model): title=models.Ch ...

  5. JavaScript splice() 、slice() 方法

    定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. slice() 方法可从已有的数组中返回选定的元素. 注释:该方法会改变原始数组. 语法 arrayObject. ...

  6. innerHTML与innerText的区别

    innerHTML获取元素的HTML内容,和设计元素的HTML内容(HTML标签会被解析)例如:ele.innerHTML="<strong>我会被解释加粗</strong ...

  7. Linux之centos系统常用命令总结

    1.查看系统版本 cat /etc/redhat-release 文件与目录操作 命令 解析 cd /home 进入 '/home' 目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 ...

  8. mybatis学习成长之路(一)

    从小白开始学习,希望自己学习的过程可以帮助更多需要的人,参考网址:https://www.cnblogs.com/ysocean/p/7237499.html 1.mybatis的jar包下载地址:h ...

  9. C#中string的相关方法

    下面的方法一般都有很多重载形式,作为初学者的我先把我用过的记录下来吧...以后用到其他的可以一点点添加: 直接上例子吧.先定义两个字符串str1,str2(不要吐槽命名==) string str1, ...

  10. ios开发-MapKit(地图框架)使用简介

    我们使用app的时候,很多软件都自带了地图功能.我们可以看到自己的位置,看到周围商场等信息.我们也可以导航,划线等. 其实苹果的MapKit使用起来还是很简单的.这里简单的介绍一下. 0.使用前准备 ...