内容:
1、泛型概述
2、使用泛型的好处
3、泛型的定义和使用
4、泛型通配符
1、泛型概述
泛型:泛泛的类型,就是一种不确定的类型(JDK1.5的一个新特性)
基本体现: <E>就是泛型,此处的E是什么数据类型?
泛型用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。
泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。
泛型的定义:定义泛型可以在类中预支地使用未知的类型。
泛型的使用:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
2、使用泛型的好处
好处如下:
- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败
- 避免了类型强转的麻烦
1 public class GenericDemo { 2 3 public static void demo1() { 4 // 创建集合对象,不使用泛型 5 // 没有明确集合存储的数据类型是什么, 什么都能存 Object 6 ArrayList array = new ArrayList(); 7 array.add("abc"); 8 array.add(123); 9 10 Iterator it = array.iterator(); 11 while (it.hasNext()) { 12 // 迭代器的方法next()返回值是什么 Object 13 // System.out.println(it.next()); 14 String s = (String) it.next(); // 打印123时报错 15 System.out.println(s); 16 } 17 } 18 19 public static void demo2() { 20 // 使用泛型(集合中的泛型) 21 Collection<String> list = new ArrayList<String>(); 22 list.add("abc"); 23 list.add("itcast"); 24 // list.add(5);//当集合明确类型后,存放类型不一致就会编译报错 25 26 // 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型 27 Iterator<String> it = list.iterator(); 28 while (it.hasNext()) { 29 String str = it.next(); 30 // 当使用Iterator<String>控制元素类型后,就不需要强转了。 31 // 获取到的元素直接就是String类型 32 System.out.println(str.length()); 33 } 34 35 } 36 37 public static void main(String[] args) { 38 demo1(); 39 demo2(); 40 } 41 }
3、泛型的定义和使用
(1)泛型的定义
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递
泛型中E的含义:
我们以ArrayList<E>为例:
类名: ArrayList<E>
方法:
- boolean add(E e);
- E get(int index)
画图说明:
(2)泛型类(含有泛型的类)
定义格式:修饰符 class 类名<代表泛型的变量> { }
使用格式:创建对象时,确定泛型的类型
1 // 泛型类定义如下: 2 class ArrayList<E>{ 3 public boolean add(E e){ } 4 public Eget(int index){ } 5 } 6 7 // 泛型类使用 8 ArrayList<String> list = new ArrayList<String>(); // 此时上面的E就是String类型 9 ArrayList<Integer> list = new ArrayList<Integer>(); // 此时上面的E就是Integer类型
(3)自定义泛型类
1 public class GenericClass<E>{//自定义的类中,可以写<>泛型 2 //E 表示未知的数据类型 调用者创建对象的时候,才能明确数据类型 3 private E e; 4 5 public void setE(E e){ 6 this.e = e; 7 } 8 9 public E getE(){ 10 return e; 11 } 12 } 13 // 使用: 14 public class GenericClassTest { 15 public static void main(String[] args) { 16 // 对自定义的泛型类,进行测试 17 GenericClass<Integer> g = new GenericClass<Integer>(); 18 // E传递什么类型就是什么类型 19 g.setE(100); 20 Integer i = g.getE(); 21 System.out.println(i); 22 } 23 }
(4)泛型方法
定义格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
使用格式:调用方法时,确定泛型的类型
上面实例中的setE方法和getE方法就是泛型方法
(5)泛型接口
定义格式:修饰符 interface接口名<代表泛型的变量> { }
使用格式:
- 1、实现接口时,确定泛型的类型
- 2、实现接口,不指定泛型的类型,直到创建对象时,确定泛型的类型
1 // 泛型接口 2 public interface Inter <E>{ 3 public abstract void show(E e); 4 } 5 6 // 泛型接口使用1 7 public class InterImpl implements Inter<Integer>{ 8 public void show(Integer i){ 9 System.out.println(i); 10 } 11 } 12 13 // 泛型接口使用2 14 public class InterImpl<E>implements Inter<E>{ 15 public void show(E e){ 16 System.out.println(e); 17 } 18 }
4、泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,
只能使用Object类中的共性方法,集合中元素自身方法无法使用。
定义:(查看ArrayList的构造方法或者addAll方法)无法在类中使用
使用:调用方法时可以给予任意类型。参照Arraylist的构造方法或者addAll方法
- ? extends E代表只要是E类型的子类即可
- ? super E代表只要是E类型的父类即可
eg:
- <? extends Animal>:表示一种泛型,这种泛型必须是Animal或Animal的子类
- <? super Animal>:表示一种泛型,这种泛型必须是Animal或Animal的父类