Anatomy of Java Generic Wildcards

"Anatomy of Java Generic Wildcards"

Iteye's editor is the most rubbish editor I've ever seen

 

There are two purposes of using generics. The first is to ensure safety, and the second is to express the advantages. After all, some semantic errors (such as type conversion) should be found at compile time as much as possible.

 

I believe everyone is familiar with generics. When we use the collection API after Java 5, we are basically dealing with generics all the time, so the author will no longer introduce some basic grammars of generics, and go directly to This chapter's topic, Unlimited wildcards for generics.

 

When we are using generics, if we do not know the actual type parameters, we can use <?> instead, this method is called unlimited wildcards, such as List<?> means that its type parameters can be any type. It is worth noting that List<?> cannot add any elements (except meaningless null) to List because it cannot be determined at compile time what type it is, and the get operation returns Object, because the compiler cannot predict you What the hell do you need to get. Some students may have doubts, this seems to be the same as Object, so why not use Object to directly replace unlimited wildcards? This is because implementing parent-child relationships between generics requires a way to represent unknown types.

 

In other words, the meaning of using List<?> is not very big , because it cannot be used as a consumer (adding data), and even some type information will be lost when acquiring data, such as:

List<?> list = new ArrayList<String>();

 

In the above program example, ArrayList<String> is actually a derived type of List<?>, but when we use get to obtain data, some type information may be lost. After all, the author mentioned before, because <?> cannot Determine its type, so it can only return Object. If that's not acceptable to you, then you can consider restricted wildcard types. After all, compared to knowing nothing about the type, at least I can clarify what conditions need to be met, which is of great help for subsequent operations.

 

There are two types of wildcards:

1. Super class limitation: <? super E>;

2. Derived limitation: <? extends E>.

 

If you use the superclass qualification, namely List<? super E>, then the type parameter can only be E itself or the superclass of E, as follows:

List<? super Integer> list = new ArrayList<Number>();

list.add(1);

/* Since the compiler can't determine its type, it is returned as Object type */

list.get(0);

 

The superclass restriction has the following limitations in operation:

1. Only add operations can be performed, and the type parameter can only be itself or a superclass;

2. When obtaining data, since the compiler does not know its type, the returned data type can only be Object.

 

Next, let's take a look at the derived qualification (subclass qualification), that is, List<? extends E>, then it also restricts the type parameter to only E itself or a derived class of E, as shown below:

List<? extends Number> list = new ArrayList<Integer>();

/* The compiler cannot determine its type, so the add operation cannot be performed */

//list.add(1);

 

list.get(0);

 

Derived qualification has the following limitations in operation:

1. Only get operations can be performed, and the type parameter can only be itself or a derived class;

2. When adding data, since the compiler does not know its type, it cannot perform the adding operation.

 

Of course, you may have questions, in which scenario should the restricted wildcard be applied? Referring to the principle of PESC (Producer Extends, Consumer Super"), when acting as a producer (obtaining operation), you should use the derived restriction: <? extends E>, so you cannot add data; when acting as a consumer (adding operation) ), you should use superclass qualification: <? super E>; when you are both a consumer and a producer, you should not continue to use generic wildcard types .

 

Guess you like

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