Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upper bound wildcard in Java Generics

after searched for a while I still couldn't find any answer to my question, even there's couple of Generics related topic, so here you go:

ArrayList<? super IOException> list = new ArrayList<Exception>();
list.add(new FileNotFoundException("this is ok."));
list.add(new IOException("This is ok"));
list.add(new ClassCastException("compile err"));//why compile err?
list.add(new Exception("compile err"));//why compile err? 

Why last two line doesn't compile? Especially the last line. I've been doing quite a bit test on this topic but still couldn't catch the logic.

Thanks.

like image 661
Kai.C Avatar asked Mar 21 '11 08:03

Kai.C


1 Answers

ArrayList<? super IOException> could be any of the following (since there is a wild card):

ArrayList<IOException>
ArrayList<Exception>
ArrayList<Throwable>
ArrayList<Object>

The code needs to work with all four possibilities.

But if it is an ArrayList<IOException>, you cannot put in a ClassCastException or an Exception, hence the compile errors.

Here's what I don't get: why this one compile------>>> list.add(new FileNotFoundException("this is ok.")); <<<----I think FileNotFoundException also below the bound of IOException. but it compiles fine.

No, FileNotFoundException is fine, because it extends IOException and you can put it in all of the four types of lists.

Note that for historical reasons, arrays do not get the same strict type checking, you can compile the following (and then get an array store exception at runtime):

   Exception[] a = new IOException[4];
   a[0] = new FileNotFoundException("this is ok.");  
   a[1] = new IOException("This is ok");
   a[2] = new ClassCastException("compiles, but boom!");
   a[3] = new Exception("compiles, but boom!"); 
like image 79
Thilo Avatar answered Oct 05 '22 23:10

Thilo