2019-01-22
内容:泛型
一、为什么要使用泛型?
原因:@解决元素数据的安全性问题
@解决获取元素时,需要类型强转的问题
出现问题两个举例
例一:
二、泛型的使用场景
使用场景:@在集合中使用泛型,见一中举例
@自定义泛型方法、泛型类、泛型接口
*泛型方法:当调用泛型方法时将会指明具体类型,此方法中所有使用此泛型的地方都会变为指定的具体类型
格式:返回值类型前加<T>
原因:@解决元素数据的安全性问题
@解决获取元素时,需要类型强转的问题
出现问题两个举例
例一:
1 @Test 2 //使用泛型的原因举例一 3 public void Test1 () { 4 ArrayList list = new ArrayList(); 5 list.add(1); 6 list.add(2); 7 list.add(3); 8 //没有使用泛型任何Object及其子类都能添加进来 9 list.add(new String()); 10 Iterator i = list.iterator(); 11 while (i.hasNext()) { 12 //强转为Integer时可能会报ClassCastException异常 13 int i1 = (Integer)i.next(); 14 System.out.println(i1); 15 } 16 }
用泛型解决上述问题
1 @Test 2 //使用泛型解决上述问题 3 public void Test2 () { 4 List<Integer> list = new ArrayList<Integer>(); 5 list.add(1); 6 list.add(2); 7 list.add(3); 8 //使用泛型后只能添加指定类型的元素,下面语句会报错,编译通不过 9 //list.add(new String()); 10 Iterator<Integer> i = list.iterator(); 11 while (i.hasNext()) { 12 //下面语句也不需要进行强转 13 int i1 = i.next(); 14 System.out.println(i1); 15 } 16 }
例二:
1 @Test 2 //使用泛型举例二 3 public void Test3 () { 4 Map<String , Integer> map = new HashMap<String , Integer>(); 5 map.put("AA", 3); 6 map.put("BB", 2); 7 map.put("CC", 1); 8 Set<Map.Entry<String, Integer>> set = map.entrySet(); 9 for (Map.Entry<String, Integer> o:set) { 10 System.out.println(o); 11 } 12 }
上面代码表明泛型可以将一个集合中的内容限定为一种指定的数据类型
二、泛型的使用场景
使用场景:@在集合中使用泛型,见一中举例
@自定义泛型方法、泛型类、泛型接口
*泛型方法:当调用泛型方法时将会指明具体类型,此方法中所有使用此泛型的地方都会变为指定的具体类型
格式:返回值类型前加<T>
1 举例:使用泛型方法完成数组到集合的转变 2 public class TestFanXing { 3 4 public static void main(String[] args) { 5 Integer[] arr = {2,6,3}; 6 List<Integer> list = new ArrayList<Integer>(); 7 list = ArrayToColl(arr, list); 8 Iterator<Integer> i = list.iterator(); 9 while (i.hasNext()) { 10 System.out.println(i.next()); 11 } 12 13 } 14 //泛型方法,将一个数组转成集合的形式输出 15 public static <T> List<T> ArrayToColl (T[] arr){ 16 List<T> list = new ArrayList<T>(); 17 for (int i = 0; i < arr.length; i++) { 18 list.add(arr[i]); 19 } 20 return list; 21 } 22 }
*泛型类:实例化泛型类之后将会指明泛型的具体类型,对应类中使用此泛型的地方都会变为指定的具体类型,但当我们定义了泛型类却在实例化时没有指明具体类型,那么默认类型是Object类型
*泛型接口:接口与类类似
三、泛型与继承的关系
若A是B的子类,则A的对象可以赋给B的对象
若a和b分别是一个泛型的两种具体指定类型的变量,则不能相互赋值
*泛型接口:接口与类类似
三、泛型与继承的关系
若A是B的子类,则A的对象可以赋给B的对象
若a和b分别是一个泛型的两种具体指定类型的变量,则不能相互赋值
1 @Test 2 public void Test4() { 3 List<Object> list1 = null; 4 List<String> list2 = new ArrayList<String>(); 5 //下面一行语句会报错 6 //list1 = list2; 7 }
四、通配符
?使用举例:
? supur A :可以存放类型A及其父类的对象
五、泛型和通配符使用注意事项
@静态方法中不能使用类泛型
@静态方法中可以使用其他泛型
@catch中不能使用泛型
@可以读取声明为通配符的集合类的对象
@不可以向声明为通配符的集合类的对象中添加元素,除了null
举例说明后两点:
?使用举例:
1 @Test 2 public void Test4() { 3 List<?> list1 = null; 4 List<String> list2 = new ArrayList<String>(); 5 list1 = list2; 6 }
? extends A :可以存放类型A及其子类的对象
? supur A :可以存放类型A及其父类的对象
五、泛型和通配符使用注意事项
@静态方法中不能使用类泛型
@静态方法中可以使用其他泛型
@catch中不能使用泛型
@可以读取声明为通配符的集合类的对象
@不可以向声明为通配符的集合类的对象中添加元素,除了null
举例说明后两点:
1 @Test 2 //读取通配符的集合类对象中元素 3 public void Test5 () { 4 List<Integer> list = new ArrayList<Integer>(); 5 list.add(1); 6 list.add(2); 7 list.add(3); 8 List<?> list1 = list; 9 Iterator<?> i = list1.iterator(); 10 while (i.hasNext()) { 11 System.out.println(i.next()); 12 } 13 }