20

Why the enhanced for loop is not performing null checking before iterating over the collection.

Sujith
  • 1,127
  • 1
  • 13
  • 20

3 Answers3

32

If you mean that this would go bang:

int[] array = null;
for (int x : array) {
}

... then I think it's entirely proper for that to throw a NullPointerException. The alternative would be for it to silently swallow the null, and treat that as equivalent to an empty array. That's not the approach Java takes anywhere else - why should this be different? It would make the language inconsistent.

The one place I wish there were more handling (but explicit handling) is switching on an enum - it would be nice to be able to provide a case for null, to avoid checking for that one special value beforehand. But that's a very different construct, which is specifically trying to take different actions for different values.

Greg Mattes
  • 33,090
  • 15
  • 73
  • 105
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    A `null` case for switching on enums is an interesting idea, but what should happen if you have a `default:` but no explicit `case null:` and the enum value is `null`. If the `null` goes to the default case that breaks backwards compatibility, and is bad if `null` is an erroneous value. If you get an NPE, then `default` is behaving in a semantically inconsistent way. (It now means "default unless its null ...") – Stephen C Oct 21 '10 at 06:20
  • 1
    @Stephen C: Good questions. I'm not sure that it's a good idea to introduce it *now*, but I think it would have been nice to consider when the feature was first introduced. – Jon Skeet Oct 21 '10 at 06:22
  • I think there are enough "wrinkles" that it would (hypothetically) have been a bad idea even then. Maybe if Java 1.0 had also had nullable tyoes ... – Stephen C Oct 21 '10 at 06:33
  • 1
    "It would make the language inconsistent." - yes, that is a problem, but not for the reason you say it is. It would be a single, rare, moment in Java where it actually wouldn't be a PITA language to use. I feel like the people creating Java looked at languages that had come before, like C and Python, and decided, "Lets make this more difficult to use than C, but have the performance of Python." I have no idea how Java ever became a language people actually chose to use when there's a whole universe of better languages, either being easier to use or having much better performance. – ArtOfWarfare Mar 20 '15 at 14:31
5

I kind of afraid to assert against Jon Skeet... :| ... But what a hell... what do you think about this scenario?:

`

findMoney(List<Places> places){
   int money = 0;
   for(Place place : places){
   money += searchWithCare(place);
   }
return money;
}

`

If I ask some client to tell me where to look and he tells me nothing. Do you think is better here to throw a NullPointerException? May be manage the call to this method so if parameter is null not call it?.... I think that return 0 is a consistent response because no error is here. I believe Exceptions are made to manage flow of code and I dont see why should I change the flow in this kind of situation. Return a cero or even a null could be a good response, couldnt it be?

So what about this solution? `

findMoney(List<Places> places){
   int money = 0;
   for(Place place : places == null ?Collections.<Place>emptyList():places){
   money += searchWithCare(place);
   }
return money;
}

`

  • This was really helpful. I've never seen the `Collections.emptyList()` idiom before. I'd have expected it to be `Collections.emptyList()` if you could do that, but apparently not. Do you know where this idiom is documented? I'm having trouble finding it. – Martin McCallion Jun 27 '14 at 09:30
  • I was trying to find it! I couldn't... it is a.. secret? :) Sorry – Francisco López-Sancho Jul 03 '14 at 11:51
  • Oh well, thanks for trying anyway. It's kin of hard to search for. – Martin McCallion Jul 03 '14 at 13:45
  • For generic methods, docs.oracle says "The type has been explicitly provided [...]. Generally, this can be left out and the compiler will infer the type that is needed" – Nikolaii99 Nov 10 '15 at 12:33
1

The code must be like this:

for (AnyObject anyObject : checkIsEmpty(anyObjectList)) {
        System.out.println(anyObject.doSomething());
}

private <T> Iterable<T> checkIsEmpty(Iterable<T> iterable) {
        return iterable == null ? Collections.<T>emptyList() : iterable;
}
Roman
  • 6,486
  • 2
  • 23
  • 41
shijin
  • 2,998
  • 1
  • 24
  • 30