First, why use generics
Reusability: The essence of generics is a parameterized type, so the use of generic code written can be reused by many different types of objects.
Security: Explicit coercion of type conversions is often required when working with parameters referenced by type object. This forced type conversion needs to be discovered at run time to convert exceptions, which can be checked at run time by introducing generics to check for type conversions, early to compile time.
Ii. Custom Generics
There are three types of custom generics in Java: generic class, generic interface, generic method.
The following example demonstrates a generic class, a generic method, and a generic interface that is similar, so it is no longer demonstrated.
//Custom generic class
PublicclassGeneric<t>
{
PrivateT second;
PublicvoidSetsecond (T newvalue)
{
second = newvalue;
}
//Custom generic method
PublicStatic<W>voidPrintvalue (W obj)
{
System.out.println (Obj.tostring ());
}
@Override
PublicString toString ()
{
returnSecond.tostring ();
}
PublicStaticvoidMain (string[] args)
{
//
generic<string> g =NewGeneric<string> ();
G.setsecond ("Zhang");
System.out.println (g);
//Using generic methods
Generic.printvalue (45);
Generic.printvalue ("Hello");
}
}
A generic method can be defined in a universal class or in a generic class. Java generics feature 1, erasing generics in Java is pseudo-generic, because during compilation, all generic information is erased and only the original type is preserved. For example, code list<double> and list<string> will become list types after they are compiled. Why does this happen? This has a great relationship with the Java virtual machine. A Java Virtual machine does not have a generic type object-----All objects belong to the normal class. Since there was no generics before java1.5, there was no generic type of code that existed with generics, and for compatibility, Java virtual machines adopted a uniform generic class. The following code is used to reflect the type erasure.
PublicStaticvoidMain (string[] args)
{
Arraylist<string> arraylist1=NewArraylist<string> ();
Arraylist1.add ("ABC");
Arraylist<double> arraylist2=NewArraylist<double> ();
Arraylist2.add (666.666);
System.out.println (Arraylist1.getclass () ==arraylist2.getclass ());
}
Output Result:
True
2. Compensation
PublicStaticvoidMain (string[] args)
{
Arraylist<string> arraylist1=NewArraylist<string> ();
Arraylist1.add ("ABC");
String str = arraylist1.get (0);//Compile normal
intstr2 = arraylist1.get (0);//Compile error
}
Arraylist1.get (0); After compilation, generics are erased and Arraylist1.get (0) returns the object type. However, because of the Java compensation mechanism, the compiler will automatically insert a string coercion type conversion. Because the int type of STR2 cannot receive the cast string type, it compiles an error. Iv. constraints of Java generics 1, cannot instantiate type parameters with primitive type such as: Error-->arraylist<double>; correct-->arraylist<double>2, Run-time type queries only apply to original Type 3, cannot create an array of parameterized types 4, cannot instantiate type variable 5, the type variable in the static context of a generic class is invalid such as: private static T; ERROR6, cannot throw or catch instances of generic classes v. wildcard types
1, limit the upper bound wildcard characters such as: list<? Extends Animal>, which represents any generic List type, its type parameter is Animal class and subclass,list<animal>, list<cat>, list<dog> are all list<? Extends Animal> subtype.
PublicStaticvoidMain (string[] args)
{
list<?extendsAnimate> animates =NewArraylist<animate> ();//OK
list<?extendsAnimate> animates1 =NewArraylist<cat> ();//OK
List<animate> Animates2 =NewArraylist<animate> ();//OK
List<animate> Animates3 =NewArraylist<cat> ();//Compile-time error
}
In fact, we can be list<extendsAnimate> animates as a collection of list<animate>, list<cat>, etc. Induction: If the given generic type is G, two specific generic parameters x, y, when Y is a subclass of X (Y extends X)
- g<? Extends y> is g< Extends subtype of x> (e.g. list<?) Extends cat> is list< The subtype of the extends animal>).
- G<x> is g< Extends X> sub-type (such as list<animal> is list<? Extends animal> sub-type)
- G<?> and g<? Extends object> equivalent, such as list<?> and list< Extends objext> equivalent
Learning here, you may encounter some doubts, or things can not understand the place, first observe the following two snippets of code, to determine whether it is feasible??
extends New Arraylist<> ();
Animal.add (New Animal ());
Animal.add (new Cat ());
None of the above two add operations can be compiled. Why is it? Since List:add (e) joins generics into List< Extends Animal>:add (? extends Animal e),? The extends animal parameter type cannot be determined, it can be animal, cat, and so on, so it is not allowed to add arbitrary objects to the list object, except NULL, in order to protect the consistency of its type.
Note: The upper bound limit is generally used on:? extends T Get () method2, limit the nether wildcard characters such as: list<? Super Cat> This wildcard is limited to all super types of Cat (including this class). Its inductive method is similar to the upper bound wildcard character, and it is not verbose here. Look at the following code:
Super New
Animates.add (new Animate ());
Animates.add (new Cat ());
The above code compiles through, the compiler does not know the exact type of the Add method, but can use any animal object (or Subtype object).
Note: The nether wildcard is typically used on the: set (? extends T>) method.
3. Unqualified wildcard characters such as: List<?> When the type is indeterminate, it is used only when the wildcard character is used less. Refer to 1, Java generic wildcard characters?
Java generic channeling-talk