A preliminary study of generic type
This code is written before generics (Generic type or generics) appear:
void Main (string[] args) { new ArrayList (); List.add ("123"); List.add ("456"); System.out.println (String) list.get (0));}
Of course, this is entirely permissible, because the contents of the list is object type, naturally any object type can be put in, can be taken out, but there are two problems in writing:
1. When an object is put into a collection, the collection does not remember the type of the object, and when the object is fetched again from the collection, the object's compilation type becomes object
2, the operation of the need to artificially cast the type to the specific target, the actual program will never be so simple, a careless will appear java.lang.ClassCastException, that is, type conversion exception
So, after the generics appear, the above code is changed to the familiar wording:
void Main (string[] args) { new arraylist<string>(); List.add ("123"); List.add ("456"); System.out.println (list.get (0));}
This is the generic type. Generics are an extension of the Java language type system, somewhat like a C + + template, where type parameters can be thought of as a placeholder for the type specified when using a parameterized type. The introduction of generics is a major feature enhancement for the Java language, bringing a number of benefits:
1, type safety. Type errors are now captured during compilation, rather than being shown as java.lang.ClassCastException at run time, moving type checking from runtime to compile to help developers find errors more easily and improve program reliability
2, eliminate many of the code coercion type conversion, enhance the readability of the Code
3, for the larger optimization brings the possibility
GetClass () Same
Look at the code:
void Main (string[] args) { new arraylist<string>new arraylist<integer>(); System.out.println (stringlist.getclass () = = Integerlist.getclass ());}
The result of the operation is:
True
This means that what generics are does not affect the type of an object instance , so it is not possible to try to define different overloaded methods by changing the way generics are:
Try to define generics using exact types
Try to define generics using exact types, and do not write an interface or parent class unless necessary:
void Main (string[] args) { new arraylist<number>(); List.add (4); List.add (2.2 For (number Number:list) System. out. println (number);}
Like this, the list is a number type, adding an integer and Double inside, which causes the get-out element to be number type, and the function of the subclass extension is lost. If you want to make the subclass Interger and Double, (Integer) list.get (0) and (double) list.get (1) will be strong, but will this not lose the meaning of generics? So, try to define generics with the exact type.
Using Type wildcard characters
List<object> is not a list<string> parent type,list<integer> is not a parent type of list<number>, attempting to assign a value in the following way is not allowed:
1 public static Span style= "color: #0000ff;" >void main (string[] args) 2 {3 list<number> numberlist = new arraylist<number> () new arraylist<integer>(); 5 numberlist = Integerlist;
The 5th line will error "Type Mismatch:cannot convert from list<integer> to List<number>". Some people may find this inconvenient: I only need to loop through a method to retrieve a list, also can not use polymorphic to put a parent type in, and can not be overloaded, what to do? In response to this problem, Java provides the developer with a wildcard "?" to see:
void Main (string[] args) { list<string> new arraylist<string>new arraylist< integer>void Printlist (list<?>for (Object o:l) System.out.println (o);
<?> is a type wildcard that represents the parent type of any generic , so that list<object>, list<string> these can be passed into the Printlist method, Note that the parameters here can not be written as LIST<E>, so the error, E is undefined. Of course <?> can not add, but this will be a warning: If you pass a list<e> to list, it is equivalent to pass a method that only promises to treat it as a list (primitive type), which will destroy type safety using generics .
Note again that you can only retrieve elements from the type wildcard, and you cannot add elements .
Generic methods
void Main (string[] args) { System.out.println (IfThenElse (false, "111", "222"static <T> T IfThenElse (booleanreturn b? First:second;}
The returned result is:
222
This means that the method can also be generalized, regardless of whether the class defined in it is generic. This means that you do not have to explicitly tell the compiler what value you want T: The compiler knows that these T must all be the same.
Static resources do not recognize generics
Pick up a topic, if you remove <T>, then:
Error, t undefined. But if we remove the static again:
There is no problem with that. In contrast, it can be seen that the static method does not recognize generics, so we have to add a <t>, and tell the static method that the following T is a generic type. Since the static method does not recognize generics, let's look at whether the static variable knows generics:
This proves that static variables do not know generics, in fact, not only static method, static variable, static block also do not know generics, you can try it yourself. Summed up is a sentence: static resources do not know generics .
Generic constraints
Can be constrained to the generic parameters, should have felt that there should be a law, and later found that no, then the conclusion of their own research, the assumption that there is a set of class inheritance relationship C inherits from B,b inherited from a:
1. When defining class, use only the extends keyword and cannot use the wildcard character "?".
Extends b>{ voidnew testmain<c>();}}
That's right. The generic type of the Testmain class can only pass a subclass of B, that is, C. "New Testmain<a> ()", "public class testmain< Extends B> "," public class Testmain<t Super b> "are the wrong wording
2. As a method parameter, generics can use the "? Extends B "or"? Super B ", the former indicates that the actual type can only be a subclass of B, the latter means that the actual type can only be a parent of B, the following two are correct:
void Main (string[] args) { print (new arraylist<c>extends b> list) {}
void Main (string[] args) { print (new arraylist<a>()); Print (new arraylist<object> ());} Super b> list) {}
3, as the parameters of local variables, generics can use "? Extends B "or"? Super B ", but the former seems to have little meaning, the latter means that only the object of the parent class can be passed, so the following is the correct wording:
void Main (string[] args) { new arraylist<b>(); List.add (new C ());}
Do not write "List.add ()", which the JDK will consider to be type mismatch.
Java syntax Sugar 3: Generics