目录
1:什么是泛型
泛型就是不确定类型,用一下几种表示<T>,其他的也行,就是规范。在java代码中随处可见,比如list<E> map<k,v>等等,容器中随处可见。用于在应用中传递对象的容器。但对象类型并不总是相同。因此,需要开发一个能够存储各种类型对象的容器。
- E:元素
- K:键
- N:数字
- T:类型
- V:值
- S、U、V 等:多参数情况中的第 2、3、4 个类型
2:为什么使用泛型,不使用object
2.1:我们使用object来试试,看看缺点在哪里
定义类:
public class Box1 {
private Object object;
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
测试代码:
@Test
public void t1() {
Box1 box1 = new Box1();
box1.setObject("张三");//编译时不会提供类型检查
System.out.println("获取值:" + box1.getObject());
box1.setObject(2);//编译时不会提供类型检查
System.out.println("获取值:" + box1.getObject());
System.out.println("=========此处出现类型不安全===========");
box1.setObject("张三");
List<Box1> list = new ArrayList();
list.add(box1);
//编译的时候报错 (此处需要自己 手动转换类型异常)
String value1 = (String) list.get(0).getObject();
System.out.println(value1);
//运行时报错 (String cannot be cast to Integer)
//证明object 不能解决 不确定的类型传入,需要小心写代码
Integer value = (Integer) list.get(0).getObject();
System.out.println(value);
}
2.2:各种泛型使用方法
使用泛型
//泛型类Box 省略getset
public class Box<E> {
private E data;
//构造函数
public Box() {
}
public Box(E data) {
this.data = data;
}
//get set
}
//泛型类Box2 验证泛型高级用法(反省范围) 省略getset
public class Box2<E extends Number> {
private E e;
public Box2(E e) {
this.e = e;
}
public Box2() {
}
}
//泛型类Map1 验证泛型高级用法(多个参数) 省略getset
public class Map1<Key,Value> {
private Key key;
private Value value;
public Map1() {
}
public Map1(Key key, Value value) {
this.key = key;
this.value = value;
}
}
// 验证泛型高级用法(多个参数) 省略getset
public class Box1 {
private Object object;
//这里定义泛型 <N extends Number>
public static <N extends Number> double add(N n,N m){
double a=n.doubleValue()+m.doubleValue();
return a;
}
//这里定义泛型 <T>
public static <T> void add1(List<?> list,T t){
if(list.indexOf(t)>0){
System.out.println("list存在元素: " + t);
} else {
System.out.println("list不存在元素: " + t);
}
}
}
测试代码:
/**
* 泛型的作用:Box
* 1:强制类型检查
* 2:减少获取的时候的类型转换
* <p>
* object 无法实现 所以用泛型
*/
@Test
public void t2() {
//1:指定泛型类型
Box<String> box = new Box<String>();
box.setData("郑州");
//box.setData(1);//编译时报错 在编译的时候提供类型检查
String s = box.getData();//编译时不报错 不需要类型转换
//int s1=box.getData();//编译时报错 强制类型检查
System.out.println("指定泛型:" + s);
//2:错误用法 不指定泛型类型 后边易出错
Box box1 = new Box();
box1.setData("洛阳");//编译不报错
box1.setData(2);//编译不报错
Integer a = (Integer) box1.getData();//编译报错 必须类型转换
System.out.println("不指定泛型:" + a);
String b = (String) box1.getData();//编译报错 必须类型转换
System.out.println("不指定泛型:" + b);//运行时报错 需要小心处理类型 是Integer 不是string
}
/**
* 多种泛型组合 Map
* 泛型的作用:
* 1:强制类型检查
* 2:减少获取的时候的类型转换
* <p>
* object 无法实现 所以用泛型
*/
@Test
public void t3() {
Map1<String, String> map1 = new Map1<String, String>();
map1.setKey("地址");
map1.setValue("北京昌平区");
System.out.println(map1.getKey());
System.out.println(map1.getValue());
System.out.println("===============");
Map1<String, Integer> map2 = new Map1<String, Integer>();
map2.setKey("年龄");
map2.setValue(222);
double d = map2.getValue();
System.out.println(map2.getKey());
System.out.println(d);
}
/**
* 有界泛型:E extends Number 只能创建子类泛型
* Number(包含基本的数值类型 byte short int long float double)
*/
@Test
public void t4() {
Box2<Long> box1 = new Box2<Long>();//可以创建Long
box1.setE(22L);
Long l1=box1.getE();
System.out.println(l1);
Box2<Integer> box2 = new Box2<Integer>();//可以创建int
box2.setE(33);
System.out.println(box2.getE());
//Box2<String> box3=new Box2<String>();//此处编译时报错 类型检查异常
}
/**
* 泛型方法
* 传递的参数类型不确定
*/
@Test
public void t5() {
int a=33;
Long d=44l;
System.out.println(Box1.add(a, d));
}
/**
* ?
* 泛型方法
* 参数类型不确定 比如传递的参数是List<Integer> 或者List<String> StrList
*/
@Test
public void t6() {
List<Integer> intList = new ArrayList<Integer>();
intList.add(2);
intList.add(4);
intList.add(6);
Box1.add1(intList,8);
List<String> StrList = new ArrayList<String>();
StrList.add("郑州");
StrList.add("洛阳");
StrList.add("北京");
Box1.add1(StrList,"洛阳");
}
2.3:总结
泛型的作用:
1:预先不知道类型,给使用者设置自己的指定类型
2:编译的时候就会进行类型检查,类型不匹配报错
3:获取值的时候需要进行类型转换了