- 泛型使用extends指定上界:<T extends superclass>, <? extends superclass>,使用super指定下界:<T super subclass>, <? super subclass>
- 指定上下界的时候,其范围包括上下界本身。
- 除了可以定义泛型类之外,还可以定义泛型方法和泛型接口
- 当指定具有一个类和一个或多个接口的边界时,使用&运算符连接它们,例如:
- class Gen<T extends Myclass & MyInterface>{//}
- 为了处理泛型转换,Java允许使用泛型类而不提供任何类型参数,这会为类创建原始类型,这种原始类型与不使用泛型的遗留代码时兼容的。使用原始类型的主要缺点时丢失了泛型的类型安全性。
// Demonstrate a raw type.
class Gen<T> {
T ob; // declare an object of type T
// Pass the constructor a reference to
// an object of type T.
Gen(T o) {
ob = o;
}
// Return ob.
T getob() {
return ob;
}
}
// Demonstrate raw type.
class RawDemo {
public static void main(String args[]) {
// Create a Gen object for Integers.
Gen<Integer> iOb = new Gen<Integer>(88);
// Create a Gen object for Strings.
Gen<String> strOb = new Gen<String>("Generics Test");
// Create a raw-type Gen object and give it
// a Double value.
// 本质上,这会创建使用Object替换类型T的Gen对象
Gen raw = new Gen(new Double(98.6));
// Cast here is necessary because type is unknown.
double d = (Double) raw.getob();
System.out.println("value: " + d);
// The use of a raw type can lead to run-time.
// exceptions. Here are some examples.
// The following cast causes a run-time error!
// int i = (Integer) raw.getob(); // run-time error
// This assigment overrides type safety.
strOb = raw; // OK, but potentially wrong
// String str = strOb.getob(); // run-time error
// This assingment also overrides type safety.
raw = iOb; // OK, but potentially wrong
// d = (Double) raw.getob(); // run-time error
}
}
- 泛型类层次:
- Gen2<T> extends Gen<T>:其中子类必须继承父类的泛型T,否则运行时无法得知父类的泛型类型。
- Gen2 extends Gen<String>:将父类的泛型实例化,作为子类的超类
- Gen2<V, T> extends Gen<T>:在父类的泛型类型基础上添加子类自己的泛型类型,子类中一参数应为父类中的泛型参数
- Gen2<V, T> extends Gen<String>
- Gen2<V, T> extends Gen
- 擦拭
- 编译Java代码时,所有泛型信息被移除(擦除)。
- 这意味着使用它们的界定类型替换类型参数,如果没有显式地指定界定类型,就使用Object
- 桥接方法:
-
- 子类中重写方法的类型擦除不能产生与超类中方法相同的擦除,对于这种情况,会产生使用超类类型擦除的方法,并且这个方法调用具有由子类指定的类型擦除的方法
// A situation that creates a bridge method.
class Gen<T> {
T ob; // declare an object of type T
// Pass the constructor a reference to
// an object of type T.
Gen(T o) {
ob = o;
}
// Return ob.
T getob() {
return ob;
}
}
// A subclass of Gen.
class Gen2 extends Gen<String> {
Gen2(String o) {
super(o);
}
// A String-specific override of getob().
String getob() {
System.out.print("You called String getob(): ");
return ob;
}
}
// Demonstrate a situation that requires a bridge method.
class BridgeDemo {
public static void main(String args[]) {
// Create a Gen2 object for Strings.
Gen2 strOb2 = new Gen2("Generics Test");
System.out.println(strOb2.getob());
}
}
-
-
- 子类Gen2扩展了Gen,但是使用特定于String的Gen版本,编译器为子类生成一个桥接方法:
-
class Gen2 entends Gen<java.lang.String>{
Gen2(java.lang.String);
java.lang.String getob();
java.lang.Object getob();
}
- 使用泛型的限制:
- 不能实例化参数:ob = new T();
- 对静态成员的一些限制:静态成员不能使用在类中声明的类型参数
- Java不支持泛型数组
- 泛型类不能扩展Throwable