Gangnus
Gangnus

Reputation: 24474

For each loop in the null list

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.

Upvotes: 7

Views: 21835

Answers (4)

davidxxx
davidxxx

Reputation: 131436

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.

Upvotes: 11

Vishwanath Kumar
Vishwanath Kumar

Reputation: 11

It will throw NullPointerException because collection is null and you are trying to iterate a collection which has referenced null. If collection is empty then it will not throw the exception and code will work fine.

Upvotes: 0

Cahit Gungor
Cahit Gungor

Reputation: 1497

foreach loop compiled into either iterator or index based loop behind scenes. Whenever it access to the iterator for the list NullPointerException is thrown for null referenced Iterable object. Though, why null check is not included in the implementation of the java foreach is another question. But I think, it keeps the distinction clearer between an empty list with a null list, which the latter one represents that something already went wrong.

Upvotes: 1

Roee Gavirel
Roee Gavirel

Reputation: 19443

It should throw the exception - plain simple.

Upvotes: 2

Related Questions