Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For each loop in the null list

Tags:

java

foreach

If we do a foreach loop in an empty collection, simply no actions will be taken. But how should work the structure in the case, when the collection is null?

Collection<String> c=null;
....
for(String item:c){
   println(item);
}

I can run the code and see the null reference exception. But what should be the behaviour exactly? I can't find any manual page about that.

I know that the exception is thrown at the header, because the collection is null. But I want to know HOW the exception is thrown. It could be done by if, or by Objects.requireNonNull(), or in some other ways, or as it is shown in the David's answer.

like image 200
Gangnus Avatar asked Mar 23 '18 08:03

Gangnus


People also ask

Does forEach work on empty list?

If the list is empty, the for-each cycle is not executed even once.

Does Java forEach check null?

1.2 In Java 8, we can use forEach to loop a Map and print out its entries. 1.3 For the Map 's key or value containing null , the forEach will print null . P.S The normal way to loop a Map will print the same above output. 1.4 If we do not want to print the null key, add a simple null checking inside the forEach .


1 Answers

A enhanced for (or foreach) after compilation uses under the hood an Iterator to iterate on the collection as stated by the JLS :

The enhanced for statement is equivalent to a basic for statement of the form:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    {VariableModifier} TargetType Identifier =
        (TargetType) #i.next();
    Statement
}

You can check if yourself by looking the disassembled code of your loop after compilation (javap -c) :

  3: invokeinterface #2,  1            // InterfaceMethod java/util/Collection.iterator:()Ljava/util/Iterator;
  8: astore_2
  9: aload_2
 10: invokeinterface #3,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
 15: ifeq          38
 18: aload_2
 19: invokeinterface #4,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
 24: checkcast     #5                  // class java/lang/String
 27: astore_3
 28: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 31: aload_3
 32: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 35: goto          9

So, it is like if you had written :

Collection<String> c = null;
for (Iterator<String> iterator = c.iterator(); iterator.hasNext();) {
    String item = iterator.next();          
}

Invoking iterator() on null throws so a NullPointerException.

like image 155
davidxxx Avatar answered Sep 21 '22 23:09

davidxxx