Generics and wildcards in Java [duplicate]

馋奶兔 提交于 2019-12-06 14:01:43

The type of the variable declaration should match the type you pass in actual object type. So:

List<Product> list = new ArrayList<Clip>();

OR

 List<Product> list = new ArrayList<Sheet>(); 

will not compile.

The reason behind this is that you might end up putting a Clip object in a list that was supposed to contain only Sheets and eventually end up treating it like a Sheet.

Developers seem to get confused because it is allowed in case of Arrays.

Product[] array = new Sheet[10]; // Compiles fine

It's allowed in case of arrays because there's a runtime exception(ArrayStoreException) that prevents you putting a wrong type of object in the array. (Consider you do this for the above array: array[0] = new Clip();)

There's not equivalent exception in case of lists because JVM knows the type of Array at run time but not of List because of type erasure.

Also, private List<Product> products; is not equivalent to private List<? extends Product> products in the sense that you can add any product or subtype of product in private List<Product> products; but you can't add anything (except null) to private List<? extends Product> products. This syntax is mostly used when you want to pass your list to a method that only reads the data from the list. Like below:

private void readProduct(List<? extends Product> list){
//read product list
}

This method will accept List<Clip> and List<Sheet> both. But adding anything to it will result in compilation error (except null).

An ArrayList<Sheet> is not a subtype of an ArrayList<Product>.

You can't use it everywhere an ArrayList<Product> is expected, especially into an ArrayList<Product> you can legally add a Clip, but you shouldn't do that with an ArrayList<Sheet>.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!