简体   繁体   中英

Java Generics usage

Kindly, why should I supply the Generic class on the left side (variable declaration) and right side (object assignment) ? I can technically skip it left or right (see alist2, or aList2), what is the drawback of aList2 and aList3 compared to aList1 ?

ArrayList<String> aList1 = new ArrayList<String>();
ArrayList<String> aList2 = new ArrayList();
ArrayList         aList3 = new ArrayList<String>();

Bonus question, just came into my mind and it compiles, but what would that mean for aList4 and aList5?

ArrayList<String> aList4 = new ArrayList<>();
ArrayList<?>      aList5 = new ArrayList<String>();

Thank you in advance.

Kind regards, Hermann

ArrayList is a raw type. The Java Spec says the following about them:

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

ArrayList<?> is a wildcard type, specifically the super type of all ArrayLists, regardless of their type parameter. As we don't know the type of elements in the List, you can do less with it than with an ordinary ArrayList. For instance, you can not add anything other than null to it, and every you take from the list is only known to be an Object .

ArrayList<> is a shorthand notation for ArrayList<X> , where X is replaced with the type parameter on the left hand side of the assignment. That is, ArrayList<String> list = new ArrayList<>() is totally equivalent to ArrayList<String> list = new ArrayList<String>() . The diamond operator only exists in Java 7 and higher, and can only be used in places where the compiler is smart enough to infer the type, but in these situations, it is usually the most type correct and concice way of using generics.

The first list is the standard version for declaring for Java 6 and earlier, to avoid grabbing raw types from the new arraylist. As of Java 7, you can use the second list just as safely.

I am unsure if the third list is safe in Java 7, but I would assume it would either store everything as objects anyhow (raw types issue) or might not even compile.

The fourth list is the essentially equivalent to the second list, and the fifth list is equivalent to the third list.

Edit: Just tested, the third list does return raw types, so I would advise against it. I also missed that the second list is missing a diamond operator on the new declaration of ArrayList (which you should have).

You should use the Generic class that is best for your implementation. That is if you only care about having a collection of items you should use Collection , if you need to preserve order you should use the interface List . The reason for this is that you should:

Program to an interface not an implementation GoF

Why is this good? Well because it makes it a whole lot easier to change implementation. Suppose that you'd like to change from ArrayList to LinkedList in the future. Then it's just a matter of changing the call to new ArrayList to new LinkedList . The same goes for your own code, try to always use an interface to any class that isn't just a dataobject. This will make you think about the interfaces between your objects instead of the implementation, that way you can always code up something crappy at first and then refine your implementation whenever you find that you need to without breaking your code.

article for more info

So why is it bad to not infer the type to your examples? Well mainly because the program won't know what types the list contains, which means that either you have to cast those objects to their type by knowing the type or by figuring out the type.

As for why aList2 is bad I'll just refer to this discussion

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM