泛型
泛型概述
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型方法 泛型类
1 /** 2 * 泛型类 3 * @author 黄旺林啊 4 * 5 * @param <T> 6 */ 7 public class User<T> { 8 9 private T data; 10 11 public User(T data) { 12 super(); 13 this.data = data; 14 } 15 16 public User() { 17 super(); 18 } 19 20 public T getData() { 21 return data; 22 } 23 24 public void setData(T data) { 25 this.data = data; 26 } 27 28 }
来个测试类
1 public class TestUser { 2 3 public static void main(String[] args) { 4 5 User<String> user1 = new User<String>("李华");//字符串型对象,用户名 6 User<Integer> user2 = new User<Integer>(789);//整形对象,用户编号吧 7 getData(user1); 8 getData(user2); 9 10 } 11 12 }
类型通配符
类型通配符一般是使用?代替具体的类型参数。例如 List<?> 在逻辑上是List<String>,List<Integer> 等所有List<具体类型实参>的父类
1 import java.util.*; 2 3 public class GenericTest { 4 5 public static void main(String[] args) { 6 List<String> name = new ArrayList<String>(); 7 List<Integer> age = new ArrayList<Integer>(); 8 List<Number> number = new ArrayList<Number>(); 9 10 name.add("icon"); 11 age.add(18); 12 number.add(314); 13 14 getData(name); 15 getData(age); 16 getData(number); 17 18 } 19 20 public static void getData(List<?> data) { 21 System.out.println("data :" + data.get(0)); 22 } 23 }
因为getData()方法的参数是List类型的,所以name,age,number都可以作为这个方法的实参,这就是通配符的作用
泛型上下界
泛型上下界,其实就是对类型的一种范围约束,比如类型Number,可以作为int、doublle等的类型上限,形式为:<T extends Number >,一般上下限和通配符用,理解如下:
类型通配符上限通过形如Box<? extends Number>形式定义,相对应的,类型通配符下限为Box<? super Number>形式,其含义与类型通配符上限正好相反
<? extends T>表示该通配符所代表的类型是T类型的子类。
<? super T>表示该通配符所代表的类型是T类型的父类。
其他补充
具有多个泛型的泛型类
有时候,一个对象的属性中,具有不同的类型属性,那么这样的类也就是需要多种类型,若要用泛型,就需要多个,如下例子:
1 /** 2 * 泛型类 3 * 多个不同类型的 4 * @author 黄旺林啊 5 * 6 * @param <T1> 7 * @param <T2> 8 * @param <T3> 9 */ 10 11 public class Bike<T1,T2,T3> { 12 13 private T1 color; 14 private T2 band; 15 private T3 price; 16 17 public Bike() { 18 super(); 19 } 20 21 public Bike(T1 color, T2 band, T3 price) { 22 super(); 23 this.color = color; 24 this.band = band; 25 this.price = price; 26 } 27 28 public T1 getColor() { 29 return color; 30 } 31 32 public void setColor(T1 color) { 33 this.color = color; 34 } 35 36 public T2 getBand() { 37 return band; 38 } 39 40 public void setBand(T2 band) { 41 this.band = band; 42 } 43 44 public T3 getPrice() { 45 return price; 46 } 47 48 public void setPrice(T3 price) { 49 this.price = price; 50 } 51 52 @Override 53 public String toString() { 54 return "Bike [color=" + color + ", band=" + band + ", price=" + price + "]"; 55 } 56 57 58 59 }
来个测试类
1 public class TestBike { 2 3 public static void print( Bike<? extends Object,? extends Object,? extends Object> bike) { 4 System.out.println(bike); 5 // System.out.println(bike.getBand()); 6 } 7 8 public static void main(String[] args) { 9 // Bike<String> bike = new Bike<String>("红色","永久牌","899"); 10 // Bike<String,String,Double> bike = new Bike<String,String,Double>("红色","永久牌",(double)899);//int 能自动转double,Intege不能自动转Double,因为他们是同级类, 11 Bike<?,?,?> bike = new Bike<>("红色","永久牌",899); 12 print(bike); 13 } 14 }