泛型(Generic)的理解和使用
泛型的定义:Jdk1.5以后出现的一种对Java语言类型的一种扩展,以支持创建可以按类型进行参数化的类,可以把类型参数看作是使用参数类型指定的类型占位符,类似形式参数是实际参数占位符一样。
使用泛型的优势:
类型安全,是编译器对泛型定义的类型做出判断限定,消除强行转化。
理解:泛型就是应用在编译时期的一种安全机制。
**泛型的擦除:**编译器对元素类型检查,通过检查生成class文件,通过检查的class文件将泛型标识符去掉。
泛型的使用:
泛型类:
声明带泛型的类格式:
Class 类名<泛型类型1,泛型类型2……>{
泛型类型 变量名;
泛型类型 方法名(){};
返回值类型 方法名(泛型类型 变量名){};
}
使用带泛型的类:
类名<具体类> 对象名= new 类名<具体类>();
例子:
package jihe;
/**
* 需求:设计一个表示点的类,该类有两个字段,横坐标x,纵坐标y,要求坐标有三种表达形式Integer,Double,String
* 分析:内部方法只有参数类型不一样,所以使用泛型简单。
**/
public class GenericDemo {
public static void main(String[] args) {
Point<Integer> p1=new Point<Integer>();
p1.setT1(5);
p1.setT2(6);
System.out.println("("+p1.getT1()+","+p1.getT2()+")");
Point<Double> p2=new Point<Double>();
p2.setT1(4.55);
p2.setT2(5.55);
System.out.println("("+p2.getT1()+","+p2.getT2()+")");
Point<String> p3=new Point<String>();
p3.setT1("99");
p3.setT2("66");
System.out.println("("+p3.getT1()+","+p3.getT2()+")");
}
}
class Point<T>{
private T t1;
private T t2;
public T getT1() {
return t1;
}
public void setT1(T t1) {
this.t1 = t1;
}
public T getT2() {
return t2;
}
public void setT2(T t2) {
this.t2 = t2;
}
}
声明多个泛型和通配符
典型案例:public interface Map<K,V>
在进行引用传递的时候,泛型类型必须匹配才可以传递,否则编译不通过。
使用"?"表示未知泛型的对象。?是通配符。
注意:
List<?>list=new ArrayList<>();
list.add(1);
会报错!
因为没有指定对象的类型,不能添加。
泛型的上线下线:
设置泛型对象的上线格式:
?extends E //接收E类型或者E的子类型。
?super E //接收E类型或者E的父类型。
package jihe;
import java.util.ArrayList;
import java.util.List;
public class FanxingTest02 {
public static void main(String[] args) {
List<String> l1=new ArrayList<String>();
l1.add("haha");
show(l1);
List<Double> l2=new ArrayList<Double>();
l2.add(3.45);
show(l2);
List<Number> l3=new ArrayList<Number>();
show(l3);
List<Object> l4=new ArrayList<Object>();
show(l4);
// up(l1); //Number 不能向下转型为String,所以会报错。
up(l2);
up(l3);
down(l3);
down(l4);
}
public static void down(List<?super Number> l){
for(Object obj:l){
System.out.println(obj);
}
}
public static void up(List<? extends Number> l){
for(Object obj:l){
System.out.println(obj);
}
}
public static void show(List<?> l){
for(Object obj:l){
System.out.println(obj);
}
}
}