1.泛型:参数化类型,即将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(类型形参),在使用/调用时传入具体的类型(类型实参)。 可以使返回结果不用强制转换
2.进一步理解:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。
在使用泛型类时,虽然传入了不同的泛型实参,但并没有真正意义上生成不同的类型,传入不同泛型实参的泛型类在内存上只有一个,即还是原来的最基本的类型(本实例中为Box),当然,在逻辑上我们可以理解成多个不同的泛型类型。
究其原因,在于Java中的泛型这一概念提出的目的,导致其只是作用于代码编译阶段,在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦出,也就是说,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段。
3.分类: 泛型接口 泛型类 泛型方法
泛型接口/泛型类:在接口或类里使用泛型,得在接口名或类名后面加上<T>
1 class Box<T> { 2 3 private T data; 4 5 public Box() { 6 7 } 8 9 public Box(T data) { 10 this.data = data; 11 } 12 13 public T getData() { 14 return data; 15 } 16 17 }
泛型方法:前提是此方法所在的类/接口没有使用泛型,在方法中使用泛型,得在返回类型前加<T>
json与pojo转化的实例,使用了com.ibm.juno包。
1 public class JSONUtil { 2 3 /** 4 * convert List<Map<String, String>>, POJO to JSON 5 * @param <T> 6 * 7 * @param <T> 8 * @param t 9 * @return 10 * @throws SerializeException 11 */ 12 public static <T> String objectToJSON(T t) { 13 try { 14 return JsonSerializer.DEFAULT.serialize(t); 15 } catch (SerializeException e) { 16 e.printStackTrace(); 17 return null; 18 } 19 } 20 21 public static <T> T jsonToObject(String json, Class<T> clazz) { 22 23 JsonParser jparser = new JsonParser(); 24 try { 25 return jparser.parse(json, clazz); 26 } catch (ParseException e) { 27 e.printStackTrace(); 28 return null; 29 } 30 } 31 }
4.Class<T> T
private T product;
private Class<T> product;
单独的T代表一个类型 而 Class<T>代表这个类型所对应的类
public T find(Class<T> clazz, int id);
根据类来反射生成一个实例,而单独用T没法做到。
等于
Map jsonString = JSON.parseObject("[21,21,21]", Map.class);
把json字符串转成特定的对象
使用 ? 代替具体的类型实参。注意了,此处是类型实参,而不是类型形参!且Box<?>在逻辑上是Box<Integer>、Box<Number>...等所有Box<具体类型实参>的父类。由此,我们依然可以定义泛型方法,来完成此类需求。
1 public class Box<T> { 2 private T data; 3 4 public Box() { 5 6 } 7 8 public Box(T data) { 9 setData(data); 10 } 11 12 public T getData() { 13 return data; 14 } 15 16 public void setData(T data) { 17 this.data = data; 18 } 19 20 }
1 public class GenericTest { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 Box<String> name = new Box<String>("corn"); 9 Box<Integer> age = new Box<Integer>(712); 10 Box<Number> number = new Box<Number>(314); 11 12 getData(name); 13 getData(age); 14 getData(number); 15 16 getData_1(name); 17 getData_1(age); 18 getData_1(number); 19 20 getData_2(name); 21 getData_2(age); 22 getData_2(number); 23 } 24 25 public static <T> void getData(Box<T> data) { 26 System.out.println("data :" + data.getData()); 27 } 28 29 public static void getData_1(Box<?> data) { 30 System.out.println("data :" + data.getData()); 31 } 32 33 public static <T> void getData_2(Box<?> data) { 34 System.out.println("data :" + data.getData()); 35 } 36 37 }
第二段代码中的三个泛型方法的写法军师正确的,但是只有后面两个是使用的通配符,只有使用通配符的才可以使用类型通配符上限,类型通配符下限
6.类型通配符上限和类型通配符下限
上限:Box<? extends Number>
下限:Box<? super Number>
7.泛型用的最多的是在集合中。
8.java中没有泛型数组一说