Generics: It allows you to specify a type parameter in a defined class, interface that is determined when declaring a variable, creating an object (that is, passing in the actual type argument, or a type argument)
Generic class or interface
"Diamond" syntax
Copy Code code as follows:
Defined
Public interface List<e> extends collection<e>
public class Hashmap<k,v> extends abstractmap<k,v> implements Map<k,v>, Cloneable, Serializable
Use
list<string> list = new ArrayList ();
Java7 You can omit the type parameter of the following angle bracket later
list<string> list = new arraylist<> ();
To derive a subclass from a generic class
Copy Code code as follows:
Mode 1
public class APP extends generictype<string>
Mode 2
public class App<t> extends generictype<t>
Mode 3
public class APP extends GenericType
Pseudo-Generics
There is no real generic class, generic classes are transparent to Java virtual machines. The JVM does not know the existence of generic classes, in other words, the JVM handles generic classes and ordinary classes. Therefore, type parameters are not allowed in static methods, static initialization blocks, static variables.
-The following are the wrong ways
Copy Code code as follows:
private static T data;
static{
T F;
}
public static void Func () {
T name = 1;
}
The following example can be used to verify from the side that no generic class exists
Copy Code code as follows:
public static void Main (string[] args) {
list<string> A1 = new arraylist<> ();
list<integer> A2 = new arraylist<> ();
System.out.println (a1.getclass () = = A2.getclass ());
System.out.println (A1.getclass ());
System.out.println (A2.getclass ());
}
Output
Copy Code code as follows:
True
Class Java.util.ArrayList
Class Java.util.ArrayList
Type wildcard character
The first thing to be clear is that Foo is the parent of Bar, but list<foo> is not a list<bar> parent. In order to represent the parent classes of various generics, Java uses the "?" To represent a generic wildcard. That is, the list<?> to represent the parent class of various generic lists. With this wildcard list generics cannot set (set) elements, only get elements. The object cannot be added because the program cannot determine the type in the list. But the object obtained must be of type object.
The following methods compile an error:
Copy Code code as follows:
list<?> list = new arraylist<> ();
List.add (New Object ());
A few ideas:
The 1.list<string> object cannot be used as a list<object> object, meaning that the:list<string> class is not a subclass of the List<object> class.
2. Arrays and generics are different: If Foo is a subtype (subclass or Sub-interface) of Bar, then foo[] is still a subtype of bar[, but g<foo> is not a g<bar> subtype.
3. To represent the parent class of the various generic lists, we need to use the type wildcard character, which is a question mark (?), passing a question mark as the type argument to the list collection, and writing:list<?> (meaning the list of unknown type elements). This question mark (?) is called a wildcard character, and its element type can match any type.
The upper limit of the wildcard character
list<? The extends supertype> represents the parent class or itself of all supertype generic list. A generic with a wildcard upper bound cannot have a set method, only a GET method.
Setting the upper limit of wildcard characters solves the following problem: Dog is a animal subclass, there is a getsize method to get the number of incoming list, the code is as follows
Copy Code code as follows:
Abstract class Animal {
public abstract void run ();
}
Class Dog extends Animal {
public void Run () {
System.out.println ("Dog run");
}
}
public class App {
public static void GetSize (List<animal> List) {
System.out.println (List.size ());
}
public static void Main (string[] args) {
list<dog> list = new arraylist<> ();
GetSize (list); Compile the error here
}
}
The reason for this error in programming here is that list<animal> is not a list<dog> parent class. Solution one can change the formal parameter list<animal> in the GetSize method to List<?>, but it is troublesome to force type conversion in each get object. The use of wildcard caps is a good solution to this problem, you can change the list<animal> to List<? Extends Animal>, the compilation is not wrong, no type conversion.
Lower bounds of wildcard characters
list<? Super subtype> represents the lower bound of the subtype generic list. A generic with a wildcard upper bound cannot have a GET method, only a set method.
Generic method
If you define a class, an interface that does not use a type parameter, but you want to define a type parameter yourself when you define a method, JDK1.5 also provides support for generic methods. The method signature of a generic method has more than a type parameter declaration than a common method's method signature. Type parameter declarations are enclosed in angle brackets, with multiple type parameters separated by commas (,), and all type parameter declarations are placed between the method modifier and the method return value type. The syntax format is as follows:
Copy Code code as follows:
Modifier return value type method name (class list) {
Method body
}
A generic method allows a type parameter to be used to represent a type dependency between one or more parameters of a method, or a type dependency between a method return value and an argument. If you do not have such a type dependency, you should not use a generic method. The collections copy method uses the generic method:
Copy Code code as follows:
public static <T> void copy (list<. Super t> dest, list<? extends t> src) {...}
This method requires that the SRC type must be a subclass of the dest type or itself.
Erase and convert
In a strict generic code, a class with a generic declaration should always carry a type parameter. However, in order to be consistent with old Java code, it is also permissible to specify no type parameters when using a class with a generic declaration. If you do not specify a type parameter for this generic class, the type parameter is called a raw type (the original), and the default is the first upper bound type specified when the parameter is declared.
When an object with generic information is assigned to another variable that has no generic information, all type information between the angle brackets is thrown away. For example, a list<string> type is converted to a list, and the list's type checking of the collection element becomes the upper bound (that is, object) of the type variable, which is erased.
Example
Copy Code code as follows:
Class Apple<t extends Number>
{
T size;
Public Apple ()
{
}
Public Apple (T size)
{
this.size = size;
}
public void SetSize (T size)
{
this.size = size;
}
Public T GetSize ()
{
return this.size;
}
}
public class Erasuretest
{
public static void Main (string[] args)
{
Apple<integer> a = new apple<> (6); ①
A's GetSize method returns an integer object
Integer as = A.getsize ();
Assign a object to the Apple variable and lose the type information in the angle bracket
Apple B = A; Ii
b only knows the type of size is number
Number size1 = B.getsize ();
The following code causes a compilation error
Integer size2 = B.getsize (); ③
}
}