1. Java paradigm is a compile-time technique that does not contain generic information at run time, and only the instance of class contains the definition information for the type parameter.
Generics are implemented through front-end processing of the Java compiler called erase (Erasure). You can (basically) think of it as a source-to-source conversion that transforms the generic version into a non-generic version. Basically, wiping out all the generic type information. All type information between the angle brackets is thrown away, so for example a list<string> type is converted to a list. All references to type variables are replaced with the upper bound of the type variable (usually object). Also, whenever the result code type is incorrect, a conversion to the appropriate type is inserted.
<T> T badCast(T t, Object o) { return (T) o; // unchecked warning }
The type parameter does not exist at run time. This means that they do not add any time or space burden, which is good. Unfortunately, this also means
You can't rely on them for type conversions.
2. A generic class is shared by all its calls
What is the result of the following code printing?
List<String> l1 = new ArrayList<String>(); List<Integer> l2 = new ArrayList<Integer>(); System.out.println(l1.getClass() == l2.getClass());
Maybe you can say false, but you think wrong. It prints out true. Because all instances of a generic class have the same runtime class (class) at run time,
Regardless of their actual type parameters.
In fact, generics are called generics because they have the same behavior for all of their possible type parameters, and the same classes can be used as many different
of the type. As a result, the static variables and methods of a class are also shared among all instances. This is why the static or static initialization of the Code
It is not legal to use a type parameter (where the type parameter is a specific instance) in the Declaration and initialization of a static variable.
3. Transformation and instanceof
Another implication of the generic class being shared by all its instances (instances) is that it is meaningless to check whether an instance is a generic class of a particular type.
new ArrayList<String>(); if (cs instanceof Collection<String>) { ...} // 非法
Similarly, type conversions like the following
Collection<string> CStr = (collection<string>) CS;
Get a unchecked warning because the runtime environment does not check for you.
4. Class-based processing
After Java 5, class becomes generic.
A change in JDK1.5 is that the class Java.lang.Class is generic. This is an interesting example of extending generics beyond the container class.
Now that class has a type parameter T, you'll probably ask, what does t mean? It represents the type represented by the class object. For example, the String.class type represents class<string>,serializable.class on behalf of Class<serializable>. This can be used to improve the type safety of your reflection code.
In particular, because the class's newinstance () method now returns a T, you can get a more precise type when you create an object with reflection. For example, suppose you want to write a tool method for a database query, given an SQL statement, and return a database that meets the query criteria
Collection of Objects (collection).
One method is to explicitly pass a factory object, like the following code:
Interface Factory<t> {
public T[] make();
}
Public <T> collection<t> Select (factory<t> Factory, String statement) {
result = new ArrayList<T>(); /* run sql query using jdbc */ for ( int i=0; i<10; i++ ) { /* iterate over jdbc results */ T item = factory.make(); /* use reflection and set all of item’s fields from sql results */ result.add( item ); } return result;
}
You can call this:
Select (New Factory<empinfo> () {
public EmpInfo make() { return new EmpInfo(); } } , ”selection string”);
You can also declare a class empinfofactory to support interface Factory:
Class Empinfofactory implements Factory<empinfo> {...
public EmpInfo make() { return new EmpInfo();}
}
Then call:
Select (Getmyempinfofactory (), "selection string");
The disadvantage of this solution is that it requires either of the following:
It is unnatural to call the lengthy anonymous factory class, or declare a factory class for each type you want to use and pass its objects to the calling place.
Using the class type parameter value is very natural and can be used by reflection. Code that does not have generics might be:
Collection emps = Sqlutility.select (Empinfo.class, "select * from Emps"); ...
public static Collection Select (Class C, String SQLStatement) {
result = new ArrayList(); /* run sql query using jdbc */ for ( /* iterate over jdbc results */ ) { Object item = c.newInstance(); /* use reflection and set all of item’s fields from sql results */ result.add(item); } return result;
}
But this does not give us a collection of the exact types we want. Now the class is generic, we can write:
collection<empinfo> emps=sqlutility.select (Empinfo.class, "select * from Emps");
public static <T> collection<t> Select (class<t>c, String sqlstatement) {
result = new ArrayList<T>(); /* run sql query using jdbc */ for ( /* iterate over jdbc results */ ) { T item = c.newInstance(); /* use reflection and set all of item’s fields from sql results */ result.add(item); } return result;
}
To get the collection we want in a type-safe way.
This technique is a very useful technique and it has become a customary usage that is widely used in the new API for processing annotations (annotations).
5. In order to ensure the compatibility of the code, the following code compiler (JAVAC) allows, type safety has your own guarantee
List L = new arraylist<string> ();
list<string> L = new ArrayList ();
6. When upgrading your class library to a generic version, use the covariant return value sparingly.
For example, the code
public class Foo {
public Foo create(){ return new Foo(); }
}
public class Bar extends Foo {
public Foo create(){ return new Bar(); }
}
Use the covariant return value style to change the bar revision to
public class Bar extends Foo {
Bar create(){ return new Bar(); }
}
Be careful of the clients of your class library.
Shanghai Shang School Java Training Original, please pay more attention. Java Related Technical articles in succession!
Java Generic Implementation Principles