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

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

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. Linux知识积累(2)dirname的使用方法

    linux中的cd "$(dirname "$0")"/是什么意思呢? 分析如下: 1.$0 表示当前动行的命令名,一般用于shell 脚本中 2.dirnam ...

  2. shuffle和sort分析

    MapReduce中的Shuffle和Sort分析 MapReduce 是现今一个非常流行的分布式计算框架,它被设计用于并行计算海量数据.第一个提出该技术框架的是Google 公司,而Google 的 ...

  3. 敏捷项目需求拆解&发现用户故事

    需求文档和敏捷中的Epic,User Story, Task之间是什么关系以及如何将需求文档转换成敏捷方式的描述,指导开发人员. 一直是很多公司团队比较困扰的问题,那么最近笔者为了解决这些问题,上了一 ...

  4. Python之面向对象四

    面向对象进阶 一.关于面向对象的两个内置函数 isinstance   判断类与对象的关系    isinstance(obj,cls)检查obj是否是类 cls 的对象,返回值是bool值 issu ...

  5. Python入门之函数的介绍/定义/定义类型/函数调用/Return

    本篇目录: 一. 函数的介绍 二. 函数的定义 三. 定义函数的三种类型 四. 函数调用的阶段 五. Return返回值 ======================================= ...

  6. 用js来实现那些数据结构(数组篇03)

    终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式.那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀疑数组在JS中的重要性与实用性.这篇文章分为 ...

  7. jsp连接书库DatabaseUtil类

    public class DatabaseUtil { private static String driver = ConfigManager.getProperties("driver& ...

  8. Linux:nohub启动后台永久进程

    nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号.在注销后使用 nohup 命令运行后台中的程序.要运行后台中的 nohup 命令,添加 ...

  9. 深度学习中Xavier初始化

    "Xavier"初始化方法是一种很有效的神经网络初始化方法,方法来源于2010年的一篇论文<Understanding the difficulty of training ...

  10. requests-所有异常归类

    IOError RequestException HTTPError(RequestException) UnrewindableBodyError(RequestException) RetryEr ...