JAVA 5支持泛型类,主要包括以下几种应用
1.简单的泛型类和接口
当指定一个泛型类时,类的声明包含一个或多个类型参数,这些参数被放在类名后面的一对尖括号内
public class TestGenericJava5<AnyType> {
private AnyType value;
public void setValue(AnyType x){
this.value = x ;
}
public AnyType getValue(){
return value;
}
public static void main(String[] args) {
TestGenericJava5 s = new TestGenericJava5<String>();
s.setValue("2222");
System.out.println(s.getValue());
}
}
也可以声明接口是泛型的如Comparable接口是泛型的如下
public interface Comparable<T> {
public int compareTo(T o);
}
2.自动装箱/拆箱
自动装箱:如果一个int型变量被传递到需要一个INteger对象的地方,那么编译器将会自动完成一个对Integer构造方法的调用。
自动拆箱:如果一个Integer对象被放到需要int的地方,则后台自动完成对intValue()方法的调用
public class TestGenericJava5<AnyType> {
private AnyType value;
public void setValue(AnyType x){
this.value = x ;
}
public AnyType getValue(){
return value;
}
public static void main(String[] args) {
TestGenericJava5<Integer> s = new TestGenericJava5<Integer>();
//自动装箱
s.setValue(2222);
//自动拆箱
int a = s.getValue();
System.out.println(a);
}
}
3.菱形运算符
可以将2中标红的代码改写为如下形式
TestGenericJava5<Integer> s = new TestGenericJava5<>();
4.通配符
为了解决泛型带来的非协变问题引入了通配符的概念。
/**
* <? extends Shape> 代表通配符
* @param arr
* @return
*/
public static double totalArea(Collection<? extends Shape> arr){
double total =0;
for(Shape s:arr){
if(s != null){
total += s.getStrokeDashOffset();
}
}
return total;
}
5.泛型的一些使用说明
1.类型界限
当我们需要限定泛型的值的界限时我们可以通过
Collection<? extends Shape> 这种形式去申明
2.类型擦除
泛型仔很大的程度上是java语言的成分而不是虚拟机的结构。泛型类可以由编译器通过所谓的类型擦除(type erasure)过程而转换成非泛型类。
编译器生成一种与泛型类同名的原始类(row class),但类型参数都被删去了。变量由她们的类型界限来替代。
3.对于泛型的限制
基本类型:基本类型不能用做类型参数。如TestGenericMemoryCell<int> 是非法的
instanceof检测:instanceof检测和类型转换工作只对原始类型进行。
TestGenericJava5<Integer> s = new TestGenericJava5<Integer>();
s.setValue(4);
Object cell = s;
//s2 unchecked
TestGenericJava5<String> s2 = (TestGenericJava5<String>) cell;
//java.lang.Integer cannot be cast to java.lang.String 对应的instanceof检测是非法的
String result = s2.getValue();
System.out.println(result);
static的语境:在一个泛型类中,static方法不可引用类的类型变量泛型类型的实例话:不能创建一个泛型类型的实例
泛型数组对象:不能创建一个泛型的数组。
参数化类型的数组:参数类型的数组的实例话是非法的。