Generics section in Effective Java

After reading the generics part of Effective Java (Second Edition) today, I feel that I am not proficient in generics, and I still need more practice.

Without further ado, let's focus:

1. Don't use prototypes

for example:

List list = new ArrayList();

When you use the list reference to point to other Lists with generics, there will be no compilation errors, only a rawtype warning will be given, but————

It's easy to sell dog meat. For example, if you point to a List<Integer>, but add a String, this will not cause any compilation errors, but

When you take it out and convert it to an Integer, a ClassCastException will appear, because you simply store a String...

If you're not sure about the type, use the "?" wildcard to suppress the warning and prevent all elements except null from being added.

2. Prefer lists over arrays

The reason is simple, arrays are covariant, generics are not. For example, if you have an array of List<String>[] (assuming legal), if you point to this generic array with an Object[] reference,

This certainly works, because arrays are covariant, but when you take the element from Object[] and call the get method to return an Integer, you'll get a cast exception. So, generics

Arrays are illegal.

3. Prioritize generics and generic methods

Needless to say, you can take a look at the source code of the collection class. Basically, generics are used. For array storage, reflection should be used to generate an array with the Arrays.newInstance() method.

The array referenced by Object is then coerced to an array of T[], which ensures the correctness of the type when adding or getting (the compiler will do it for you).

Generic methods are very powerful methods:

public static <T> void swap(List<T> list, int i, int j)

This generic method can automatically catch exceptions, including when the parameter you pass in is List<?>, but at this time, the wildcard character ? is captured. It is recommended to use it only in void methods.

4. PECS principles

That is, the generic type of the producer of T is <? extends T>, and the generic type of the consumer of T is <? super T>.

The reason is very simple. The main method provided by the producer is the get() method, and Java's generics are erased at runtime, that is, the T here becomes Object,

At the "boundary" of calling or leaving the method, the compiler will transform according to the generic parameter T, that is, the object type obtained by calling the producer get method is consistent

It is converted to T type, indicating that no matter what type it is, as long as the T type can be accessed (it is a subtype of T). The main method provided by consumers is add()

(or other consume(), etc.), at this time, it indicates that the type of consumer consumption is only the parent type of T, which is the object consumed when the add() method is called.

Both are T or a supertype of T, with guaranteed lower bounds.

Summary: To better understand generics, you must practice and think more, grasping the fact that generics are erased at runtime, and you can master the use of most generics

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326610967&siteId=291194637