泛型类声明时,在类名后面的尖括号内,放置一个或多个类型参数
class GenericMemoryCall<AnyType> {
private AnyType storedValue;
public AnyType read() {
return storedValue;
}
public void write( AnyType x ) {
storedValue = x;
}
}
泛型接口的声明方式同泛型类是一致的,在接口名后紧跟一个尖括号,里面放置类型参数
interface Comparable<AnyType> {
public int compareTo( AnyType other );
}
显示泛型方法的声明同普通方法类似,唯一不同:在方法声明处执行一个泛型类型,显示的表明该方法是泛型方法
public static <AnyType> boolean contains( AnyType[] arr, AnyType x ) {
for( AnyType val : arr ) {
if( x.equals( val ) ) {
return true;
}
}
return false;
}
<AnyType>
显示表明该方法是泛型方法, 且该泛型类型还可以指定泛型类型界限
这个例子里要求:泛型必须实现了Comparable<?>
接口,且该接口里的类型必须是泛型类型及其超类
public static <AnyType extends Comparable<? super AnyType>> AnyType findMax( AnyType[] arr ) {
int maxIndex = 0;
for( int i = 1; i < arr.length; i++ ) {
if( arr[i].compareTo( arr[ maxIndex ] ) > 0 ) {
maxIndex = i;
}
}
return arr[ maxIndex ];
}
?
通配符表示参数类型的子类(或超类):extends
表示子类, super
表示超类
// 子类 - 只能接收Shape类及其子类
public static double totalArea( Collection<? extends Shape> arr ) {
double total = 0;
for( Shape s : arr ) {
if( s != null ) {
total += s.area();
}
}
return total;
}
// 父类 - 只能接收Shape类及其父类
public static double totalArea( Collection<? super Shape> arr ) {}
泛型类可以由编译器通过所谓的类型擦除(type erasure)过程而转变成非泛型类。编译器生成一种与泛型类同名的原始类(raw class),但是类型参数都被删去了。类型变量由它们的类型界限来代替,当一个具有擦除返回类型的泛型方法被调用的时候,一些特性自动被插入。如果使用一个泛型类而不带类型参数,那么使用的是原始类
由于类型擦除的存在,有以下的限制需要遵守:
GenericMemoryCell<int>
就是错误的,必须使用基本类型的包装类GenericMemoryCell
(编译器生成的与泛型类同名的原始类,但是删去了参数类型!)
但是最后一行中,由于对read()
的调用企图返回一个String
对象会产生一个运行时错误,该方法在运行时只能返回类型边界值 - 此例中为______Object
public void instanceofLimitation() { GenericMemoryCell<Integer> cell_int = new GenericMemoryCell<>(); cell_int.write( 4 ); Object cell_obj = cell_int; GenericMemoryCell<String> cell_str = (GenericMemoryCell<String>) cell_int; String s = cell_str.read( ); }
T obj = new T();
中右边的实例化是非法的T[] arr = new T[10];
中右边的数组实例化是非法的ClassCastException
异常,原因见instanceof检测
public void f() { GenericMemoryCell<String>[] arr_str = new GenericMemoryCell<> 10 ; GenericMemoryCell<Double> cell_double = new GenericMemoryCell<>(); cell_double.write( 4.5 ); Object[] arr_obj = arr_str; arr_obj 0 = cell; String s = arr_str 0 .read(); }
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。