1, the generic mechanism is supported by JAVA5, and code written using a generic mechanism has better security and readability than those that use the object variable in a cluttered manner and then force the type conversion.
Generic programming means that the code you write can be reused by many different types of objects, and generic programming is implemented by inheriting object before generics come out. But there are drawbacks: 1, when getting a value you must force the type conversion. 2, there is no type check error, the runtime will not error. Generics provide a type parameter that resolves this issue.
2, define the generic class (generic classes). Format:
public class Pair<t, u>{...}
T, U is a type variable
A type variable in a class definition specifies the return type of the method and the type of the domain and local variables, such as
Private T var;
Public T GetFirst (t a) {
return var;
}
Called when: pair<string, integer>
generic method, Format:
Class Arraylog {
public static <T> Getmiddle (T ... a)
{
return a[a.length];
}
}
This is defined in the normal class, not defined in the generic class, which is a generic method. The type variable is placed after the modifier, before the type is returned. (can be defined either in a normal class or in a generic class).
When called, the specific type is added before the method name (in most cases, the compiler can infer that it is looking for a common super type).
3, type variables are qualified, classes and methods need to be constrained to type variables.
T extends parents; The parents, which indicates that T is a subtype of the type.
There are multiple qualifiers that can be used with the "&" symbol to isolate type variables, and can have multiple interfaces, but at most one class.
4, there is no generic type in the virtual machine, all objects are normal classes.
Whenever a generic type is defined, a primitive type (raw type) is provided, and the original data type name is the generic type name after the type parameter is deleted. Erase the type variable and replace the qualified type (unqualified with object).
The original type is replaced with the first qualified type variable, and if it is not, it is replaced with an object.
Translation type expression:
When a generic method is called, the compiler inserts a forced type conversion if the return type is erased. Cases:
Pair <Employer> budies = ...
Employer Buddy = Buddies.getfirst ();
The compiler inserts a forced type conversion code.
You also force the insertion of the type conversion code when accessing a generic field.
Translation of generic methods, methods of wiping out brings two problems. Example:
Class DateInterval extends Pair<date> {
public void Setsecond (Date second)
{
.....
}
...}
When it is wiped out, however, it becomes:
Class Dateinteval extends Pair {
public void Setsecond (Date second) {
}
}
However, there are also setsecond methods inherited from the parent class, public void Setsecond (Object second);
You want the call to be polymorphic, so you need to generate a bridge method (Brige).
public void Setsecond (object second) {
Setsecond ((Date) second);
}
There is also a possibility that there are two different methods of return value types:
Date Getsecond () {
Return (Date) Super.getsecond (). Clone ();
} Define Yourself
Ojbect Getsecond () overrides inheritance.
The code cannot be written like this, but the compiler can handle it correctly and the virtual machine can handle it correctly, such as the Clone method.
In short: Need to remember the following generic conversion facts
There are no generic types in the virtual machine
All type parameters are replaced by their qualified type.
The bridge method is synthesized to maintain polymorphism
To maintain type safety, you must insert a forced type conversion
5, Constraints and limitations
You cannot use the base type data as a typed parameter.
Run-time type queries only work with the original data, and there will be a compiler warning whenever a instaceof is used or if a type conversion is involved in a generic type.
You cannot create an array of parameterized types, but allow you to declare typed arrays. pair<string> [] p = new Pair<string>[10];//error
A mutable parameter passes a generic parameter, and only generates a warning, not an error.
You cannot instantiate a type variable, such as new T (). T.class and so on.
First = T.class.newinstance ()//error
But can be designed like this: pulic static <T> pair<t> Makepair (class<t> cl) {
{
try {return new pair<> (Cl.newinstance (), Cl.newinstance ())}
catch (Exception ex) {return null;}
}
Pair<string>p = Pair.makepair (String.class);
Cannot create a generic array: T [] P = new T[10]//error; Equivalent to Object [] p = new Object [10];
If there is a type variable, you can do this, such as:
public static <t extends comparable> t[] MINAMX (T ... a) {
t[] mm = (t[]) array.newinstance (A.getclass.getcomponenttype (), 10);
}
For example, in the arrays class, object[] ToArray (); T[] ToArray (t[] result);
You can no longer reference a type variable in a static domain or method.
An instance of a generic class cannot be thrown or captured. public class Problem<t exents exceptino>{...} Error
A catch clause cannot use a type variable. catch (T e)//error.
However, it is normal to use it in the exception specification.
public static <t extends throwable> void doWork (T t) throw t
{
try {
do work;
} catch (Throw Realcautse) {
T.initcase (Realcasu);
Throw T;
}
}
can be used to eliminate checks for checked exceptions. You must provide a processor for each checked exception, which is troublesome in the thread. Can simplify:
Public block{
public static <t extends throwable> void Throwas (Throwable e) throw T
{
Throw (T) e;
}
}
The following code will be converted to an unchecked exception:
try {
Do work
} catch (Throwable t) {
Block.<exceptions>throwas (t);
}
Very useful in multi-threading: The user only needs to overwrite the body method to provide a specific call to Tothread, the object that gets the thread class, and its run method does not mind the exception that has been checked. Tricked the compiler.
Public abstract class block{ Publci abstract void Body () throws Exception; Public Thread Tothread () {return new Thread () {Public void Run () {try {body (); }catch (Throwable t) {block.<runtimeexception> Throwas (t); } };} Public static <t extends throwable> void Throwas (Throwable e) throw T{throw (T) e;} } When a generic type is wiped out, the condition that caused the conflict cannot be created. class pair<t>{Public Boolean equals (T o) {//errorreturn true; }
After type erasure, the Equals method in Ojbect is not overwritten. is overloaded, but two has conflicts.
To support the erase transformation, you need to force the restriction that a class or type variable cannot be a subclass of two interface types at the same time, and these two interfaces are different parameters of the same interface.
6, generic wildcard character:? Extends parents: Upper limit:? Super Son: Lower limit, super type.
Dark Horse programmer--java Learning Note nine (generics)