E–element (used in collections, because elements are stored in the collection)
T–type (Java Class)
K–key (Key)
V–value (value)
N–number (numeric type)
? – Indicates an indeterminate Java type (unrestricted wildcard type)
S, U, v–2nd, 3rd, 4th types
object– is the root class of all classes, objects of any class can be set to the object reference variable, when used may require type casting, but with the use of generic T, E and other identifiers, before the actual use of the type has been determined, do not need to cast a type.
? Wild-Letter wildcard type
<? Extends t> represents the upper bound of the type, which indicates that the parameterized type may be a subclass of T or T
<? Super t> represents the lower bound of the type (called the superclass in Java core), which indicates that the parameterized type is a supertype of this type (the parent type) until the object
Type erase in Java we mentioned: the first step in type erase--Replaces all generic parameters with their leftmost (top-level parent) type.
The left-hand side of here can be represented by extends.
When generating bytecode for a generic class, the compiler replaces the type parameter with the erase of the type parameter. For an unrestricted type parameter (), its erase is Object. For the upper-type parameter (>), its erase is the upper bound (in this case, comparable). For type parameters with more than one limit, use their most left-bound erase.
Extends
The upper bounds are declared with the extends keyword, which indicates that the parameterized type is either the specified type or a subclass of this type.
For example, we now define: List<? extends T>
First you can easily misunderstand it as a collection of all classes that inherit from T, and you might think that the list you define could be used to put any subclass of T, so let's take a look at the following code:
ImportJava.Util.LinkedList;ImportJava.Util.List;/** * @author Hollis * *Public ClassTestgeneric{ Public Static voidMain(String[]Args) { List<? Extends Season>Seasonlist= New LinkedList<> ();Seasonlist.Add(New Spring()); } }class season {}< Span class= "KWD" >class spring extends season{< Span class= "PLN" >}
seasonList.add(new Spring());
The Guild error: The method put (Spring) is undefined for the type list<capture#1-of? Extends season>
list<? Extends season> means "with any list of inherited types from Season", the compiler cannot determine the type that the list holds, so it is not safe to add objects to it. You can add null, because null can represent any type. So the Add method of the list cannot add any meaningful elements, but it can accept the existing subtype list assignment.
You may be trying to do this:
List<? Extends Season> seasonlist = new< Span class= "PLN" > linkedlist<spring> (); seasonlist.add (new spring ());
However, even if spring is indicated, you cannot add a spring object with the Add method.
Why can't I join the subclasses of the season class and the season class in the list because of this:
List<? extends Fruit>
Indicates that the upper limit is fruit, and the following assignment is legal
List<? Extends Season>List1= New ArrayList<Season> (); List<? Extends Season>List2= New ArrayList<Spring> (); list<? extends season> List3 = new< Span class= "PLN" > arraylist <winter> ();
If list<? Extends season> support the method of the Add method is valid
List1 can add season and all season subclasses
List2 can add spring and all of the spring subclasses
List3 can add winter and all winter subclasses
In that case, the problem will arise.
List<? extends Season>
The object that should be held is the subclass of season, and specifically which subclass is unknown, so adding any season subclass will be problematic,
Because if add spring, it may list< Extends season> holds the object is new ArrayList ()
Spring's addition is certainly not possible, if add winter words, may list<? Extends season> holds a subclass of new Arraylist<jonathan > ()
Winter's accession is not legal, so list< Extends season> list cannot be add
However, this form is still useful, although you cannot use the Add method, but you can specify a different type of season at initialization time. Like what:
list<? Extends season> List1 = Getseasonlist (); The//getseasonlist method returns a list of the Season subclasses
In addition, since we have ensured that the list holds the season class or one of his subclasses, you can get the value directly using the Get method:
List<? Extends Season>Seasonlist= New LinkedList();SpringSpring= (spring) Seasonlist.get (0 ); season= Seasonlist< Span class= "pun". get ( 1)
Super
The Nether is declared with Super, which indicates that the parameterized type may be the type specified, or the parent type of this type, until object.
Such as:
List<Fruit>Fruits= New ArrayList<Fruit> ();List<? Super Apple> =Fruits;Fruits.Add(New Apple()); WorkFruits.Add(New Redapple()); WorkFruits.add ( fruit //compile error fruits. add (new object ()); //compile error
The fruits here is a list of Apple's superclass (parent class, superclass). Similarly, for type safety reasons, we can add an Apple object or any of its subclasses (such as a redapple) object, but because the compiler does not know what the list's content is, it is not allowed to join a particular superclass.
And when we read it, the compiler can only return object objects without knowing what type it is, because object is the final ancestor class of any Java class.
Pecs Principles
If you want to read data of type T from the collection and cannot write, can I use the? extends wildcard character; (Producer extends)
If you want to write data of type T from the collection and you do not need to read it, you can use it? Super wildcard; (Consumer Super)
If you need to save and fetch, do not use any wildcard characters.
Resources:
The pecs principle in Java generics
http://www.hollischuang.com/archives/255
Understanding of extends and super in Java Generics (GO)