先来看下面这段代码,map被声明为Map<String, String>类型
1 Map<String, String> map = new HashMap<>(); 2 map.put("hello", "你好"); 3 map.put("how are you?", "吃了没?"); 4 System.out.println(map.get("hello")); 5 System.out.println(map.get("how are you?"));
再来看这段代码反编译后的情况
1 Map<String, String> map = new HashMap(); 2 map.put("hello", "你好"); 3 map.put("how are you?", "吃了没?"); 4 System.out.println((String)map.get("hello")); 5 System.out.println((String)map.get("how are you?"));
泛型,又称作参数化类型,顾名思义是给类型增加了参数,那么为什么要给类型增加参数呢?设想不加参数的情况,map.get的返回类型是Object,我们在使用该返回对象时必须手动强制转换成需要的类型才能进行相应操作(jdk5之前就不得不这样做),手动强制转换就存在类型安全问题(ClassCastException),所以泛型出现了。说白了,java的泛型就是编译器替你进行强制转换,并在编译期就能提前发现类型安全问题。
泛型的使用
泛型接口、泛型类、泛型方法
1 //GenericInterface也可以指定泛型类型,如String,其实现genericInterface也需要为String。 2 //但如果GenericInterface需要泛型T,T必须要在GenericClazz上先声明,不然无法识别。 3 public class GenericClazz<T> implements GenericInterface<T> { 4 private T t; 5 6 //对应GenericClazz上的T 7 public GenericClazz(T t) { 8 this.t = t; 9 } 10 //GenericInterface接口方法的实现 11 @Override 12 public void genericInterface(T t) { 13 System.out.println(t.getClass().getName()); 14 } 15 //泛型方法的泛型可以覆盖泛型类上的泛型 16 public <T> void genericFunction(Class<T> clazz) { 17 System.out.println(clazz.getName()); 18 } 19 } 20 21 public interface GenericInterface<T> { 22 void genericInterface(T t); 23 }
泛型中的通配符,以及指定泛型的上下限
1 public class GenericWildcard { 2 @Test 3 public void test() { 4 5 Box<String> name = new Box<>("corn"); 6 Box<Integer> age = new Box<>(12); 7 Box<Number> number = new Box<>(345); 8 9 getData(name); 10 getData(age); 11 getData(number); 12 13 // getCeilingNumberData(name);//编译出错 14 getCeilingNumberData(age); 15 getCeilingNumberData(number); 16 17 // getFloorIntegerData(name);//编译出错 18 // getFloorIntegerData(age);//编译出错 19 getFloorIntegerData(number); 20 } 21 22 private void getData(Box<?> data) { 23 System.out.println("data :" + data.getData()); 24 } 25 private void getCeilingNumberData(Box<? extends Number> data){//指定Number为泛型的上限,Integer、Number符合 26 System.out.println("data :" + data.getData()); 27 } 28 private void getFloorNumberData(Box<? super Number> data){//指定Number为泛型的下限,只有Number符合 29 System.out.println("data :" + data.getData()); 30 } 31 }
Box类型
1 public class Box<T> { 2 3 private T data; 4 5 public Box() { 6 } 7 8 private Box(T data) { 9 setData(data); 10 } 11 12 private T getData() { 13 return data; 14 } 15 16 private void setData(T data) { 17 this.data = data; 18 } 19 }