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

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

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. GIT入门笔记(15)- 链接到私有GitLab仓库

    GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的功能,能够浏览源代码,管理 ...

  2. Spring Security入门(2-3)Spring Security 的运行原理 3

    关键组件关系 FilterSecurityInterceptor--- authenticationManager --- UserDetailService--- accessDecisionMan ...

  3. python基础——面向对象进阶

    python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...

  4. 框架学习之Struts2(四)---拦截器和标签

    一.拦截器概述 1.1 在struts2框架中封装了很多功能,struts2里面封装的功能都是在拦截器里面,struts2里面又很多拦截器,但不是每次这些拦截器都执行,每次执行型默认的拦截器. 默认拦 ...

  5. css常见属性

    css常见属性 1.颜色属性 1.1 color属性定义文本的颜色 1.2 color:green 1.3 color:#ff6600 可简写为#f60 1.4 color:rgb(255,255,2 ...

  6. C# 获取网页源代码

    /// <summary> /// 获取网页源代码 /// </summary> /// <param name="url"></para ...

  7. 用golang实现常用算法与数据结构——跳跃表(Skip list)

    背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...

  8. TNS-12560: Message 12560 not found; No message file for product=network, facility=TNS报错

    [oracle@localhost bin]$ ./lsnrctl startLSNRCTL for Linux: Version 12.2.0.1.0 - Production on 17-APR- ...

  9. HTML5中meta属性大集合

    1.声明文档的字符编码 <meta charset='utf-8'> 2.声明文档的兼容模式 <meta http-equiv="X-UA-Compatible" ...

  10. Plupload 上传控件使用指南

    本文转载至(感谢原作者分享):http://www.cnblogs.com/2050/p/3913184.html#plupload_doc2 我之前写过一篇文章<文件上传利器SWFUpload ...