泛型(Generics JDK5.0之后添加,方便代码简化)
类型参数:把数据类型类当成一个参数在<>里面进行传递,不能写基本类型,一般用大写的字母来表示,比如T,M... 使用方式:1、泛型类/接口
1)声明类时,使用类型参数,用于构造方法:
public class GenericDemo<T> {//声明类时,使用类型参数,代表
T a;
public GenericDemo(T number){//number类型参数,里面存放int,long,double类型
a=number;
}
public void print(){
System.out.println(a);
}
public static void main(String[] args) {
GenericDemo<Integer> g1=new GenericDemo<Integer>(100);
GenericDemo<Double> g2=new GenericDemo<Double>(4.5);
g1.print();
g2.print();
}
}
用于普通方法参考代码:
<pre name="code" class="java">public class GenericClassDemo<T> {
T t;//t可以是任何类型,根据实例化类传的类型参数一致
public void setT(T t){//在泛型中使用类型参数的方法,自动成为泛型方法
this.t=t;
}
public T getT(){
return t;
}
public static void main(String[] args) {
GenericClassDemo<Integer> g1=new GenericClassDemo<Integer>();
g1.setT(1000);
System.out.println(g1.getT());
GenericClassDemo g2=new GenericClassDemo();//可以这样写
g2.setT(1);//调用不写泛型,就是Object类型
}
}
2)泛型接口:
public interface List<E>
2、泛型方法,分为:
1)在泛型类中使用类型参数的方法,自动成为泛型方法;
2)非泛型类中可以单独定义泛型方法
public class GenericMethodDemo {
//非泛型类中的泛型方法
public <T> T getValue(T i){
return i;
}
public static void main(String[] args) {
GenericMethodDemo g=new GenericMethodDemo();
System.out.println(g.getValue(1000));//T-->Integer
System.out.println(g.getValue(new GenericMethodDemo()));//返回对象的内存地址
}
}
注意:泛型在对类型有特殊操作时不能使用,比如加法计算只能是数字,则不能使用泛型
3、类型参数写多个:写法<T,M>,2个类型可以相同
4、实现类型参数安全性
1)类型自变量:指尖括号中的类型名
2)类型推断:java提供泛型写法灵活型,当编译器可以根据上下文推断类型自变量的类型时,则允许保留类型参数为空;例如:
GenericClassDemo<Integer> g1=new <span style="color:#FF0000;">GenericClassDemo<></span>();
g1.setT(1000);
System.out.println(g1.getT());
因为java对类型参数实例化分配内存时,与指定的类型无关
3)空的类型参数:<>,又称钻石运算符或菱形运算符
5、泛型认为子类和父类是2种不同的类,所以不能相互转换,如下代码是错误的:
GenericClassDemo<Number> g1=new GenericClassDemo<Integer>();
6、通配符:类型自变量的特殊写法,是对于类型自变量的类型限定,包含以下三种:
1)? extends C1 代表C1类的所有子类
2)? super C2 代表C2类的所有父类
3)? 代表所有类
用法参考代码:
public class WildCarDemo<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
//T代表所有类
//<? extends Number> 代表所有继承自Number的类,Number的子类
public boolean compare(WildCarDemo<? extends Number> wcd){
if(t==wcd.t){
return true;
}
return false;
}
public static void main(String[] args) {
//泛型认为子类和父类是2个不同的类型,不可以互换
//List<Integer> list1=new ArrayList<Number>();
WildCarDemo<Integer> w1=new WildCarDemo<>();
w1.setT(1000);
WildCarDemo<String> w2=new WildCarDemo<>();
w2.setT("abc");
//w1.compare(w2);//编译出错,因为w2类型自变量不满足? extends Number条件,所以报编译错误
WildCarDemo<Double> w3=new WildCarDemo<>();
w3.setT(4.5);
w1.compare(w3);//因为Double是Number的子类,所以可以编译通过
}
}