开发者

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.


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!"); 


Consider the same declaration of list, but with a different assignment:

ArrayList<? super IOException> list = new ArrayList<IOException>();

No change in the type of list, but now adding a ClassCastException or Exception is clearly wrong.


Exception is the superclass as IOException extends Exception. You could use:

 List<Exception> list = new ArrayList<Exception>();
 list.add(...); // any exception

Then it will compile for all exception types.


To me this refers to lower boundend Wildcards: <? super IOException>. Upper bounded wildcards would be <? extends IOException>.

The wildcard in your example seems effective only in the line the new Object is assigned to the variable. When later accessed, it is obviously no longer effective. It is then just the same as ArrayList<IOException>.

So your explanation to yourself is apparently wrong. Upper bounded and lower bounded means what it says.


i think because the last to exceptions aren't derived from the base class IOException


As per your ArrayList reference generic declaration, You can only add actual IOException (Because of ? super) or the objects which extends IOException in to the list.

ClassCaseException and Exception are not derived from IOException, so it fails.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜