什么是泛型? 泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型来代替
泛型也可以看作是一个变量,用来接收数据类型 E e:Element 元素 T t :Type 类型 泛型可以接收任意的数据类型,可以使用Integer,String,Object。。。 创建对象的时候确定泛型的数据类型
/** * 定义一个带有泛型的类 * @param <E> */ public class GenericClass<E> { private E name; public E getName() { return name; } public void setName(E name) { this.name = name; } } package collection_demo.generic_demo; import java.util.ArrayList; import java.util.List; /** * 测试含有泛型的类 */ public class demo { public static void main(String[] args) { //把GenericClass泛型指定为String类型 GenericClass<String> g1 = new GenericClass<>(); g1.setName("王八蛋"); System.out.println(g1.getName()); List<String> list = new ArrayList<>(); list.add("王一蛋"); list.add("王二蛋"); list.add("王三蛋"); list.add("王四蛋"); //GenericClass泛型指定为List<String> GenericClass<List<String>> g2 = new GenericClass<>(); g2.setName(list); List<String> list1 = g2.getName(); for (String name : list1) { System.out.println(name); } } }定义含有泛型的方法: 泛型定义在方法的修饰符和返回值之间 格式:修饰符<泛型> 返回值类型 方法名(参数列表(泛型)){ 方法体; }
调用含有泛型的方法: 传递什么类型,泛型就是什么类型
eg:
package collection_demo.generic_demo; /** * 定义含有泛型的方法 */ public class GenericMother { /** * 定义只有一个参数为泛型的方法 * 且返回值类型也是泛型的成员方法 * @param m * @param <M> */ public <M>M mother(M m){ return m; } /** * 定义一个带泛型的静态方法 * @param m * @param <M> */ public static <M>void mother2(M m){ System.out.println(m); } /** * 定义多个泛型参数的成员方法 * @param m * @param s * @param <M> * @param <S> */ public <M,S>void mother(M m,S s){ System.out.println(m); System.out.println(s); } } package collection_demo.generic_demo; /** * 测试含有泛型的方法 */ public class GeneriMotherDemo { public static void main(String[] args) { //创建对象,准备用来调用含有泛型的方法 GenericMother gmd=new GenericMother(); //调用有返回值且含有一个泛型参数的方法 传递什么类型的参数 则泛型就是什么类型 Integer integer = gmd.mother(890); System.out.println(integer); //调用没有返回值含有两个泛型参数的方法 传递什么类型的参数 则泛型就是什么类型 gmd.mother(890,12.34); //调用没有返回值含有一个泛型参数的方法 传递什么类型的参数 则泛型就是什么类型 GenericMother.mother2("你好"); } }泛型在接口的使用方式: eg:
package collection_demo.generic_demo; /** * 创建一个带有泛型的接口 * @param <E> */ public interface GenericInterface<E> { public abstract void mother(E e); }1.实现接口时并为泛型指定数据类型 例子:可以参照Scanner类实现Iterator接口并把泛型指定为String eg:
package collection_demo.generic_demo; /** * 实现带有泛型的接口的实现类 * 并且指定了泛型 */ public class GenericInterfaceImpl01 implements GenericInterface<String> { @Override public void mother(String s) { System.out.println(s); } }2.实现接口时不指定泛型,就像ArrayList实现List一样,继续保留泛型 等创建对象时再指定泛型的类型
eg:
package collection_demo.generic_demo; /** * 第二种实现泛型的接口 * 不指定泛型,等创建对象时再指定泛型 * @param <E> */ public class GenericInterfaceImpl02<E> implements GenericInterface<E> { @Override public void mother(E e) { System.out.println(e); } }泛型的通配符: ?:代表任意的数据类型 使用方式: 1.不能创建对象使用 2.只能作为方法的参数使用 eg:
package collection_demo.generic_demo; import java.lang.reflect.Array; import java.util.ArrayList; /** * 泛型的通配符: * ?:代表了任意的数据类型 * 使用方式: * 不能创建对象使用 * 只能作为方法的参数使用 * */ public class GenericDemo01 { public static void main(String[] args) { ArrayList<String> list1=new ArrayList<>(); list1.add("王一蛋"); list1.add("王二蛋"); list1.add("王三蛋"); mother01(list1); ArrayList<Integer> list2=new ArrayList<>(); list2.add(12); list2.add(16); list2.add(15); mother01(list2); } /** * 定义一个方法,能遍历所有类型的ArrayList集合 * 这个时候我们不知道ArrayList集合使用什么数据类型 * 所以要使用泛型的通配符 ? 来接收数据类型 * * 注意:泛型没有继承概念的 * 所以 ArrayLIst<Object>不能接收ArrayList<String> * * @param list */ private static void mother01(ArrayList<?> list) { for (Object obj:list){ System.out.println(obj); } } }泛型的高级使用: 泛型的上限限定: ? extends E 代表使用的泛型只能是E类型的子类或自己本身的类型 泛型的下限限定: ?super E 代表使用的泛型只能是E类型的父类或自己本身的类型 eg:
/** * 泛型的高级使用 * * 泛型的上限限定: * ? extends E 代表使用的泛型只能是E类型的子类或本身 * ? super E 代表使用的泛型只能是E类型的父类或本身 */ public class GenericDemo02 { public static void main(String[] args) { ArrayList<Integer> list1=new ArrayList<>(); ArrayList<String> list2=new ArrayList<>(); ArrayList<Number> list3=new ArrayList<>(); ArrayList<Object> list4=new ArrayList<>(); //mother1(ArrayList<? extends Number> list) //因为list1的泛型Integer是继承于Number的,所以不会报错 mother1(list1); //因为list2中的泛型String不是Number类型子类,所以报错 mother1(list2); //规则同上 mother1(list3); //规则同上 mother1(list4); //mother2(ArrayList<? super Number> list) //因为list1,list2不是Number的父类或其本身,所以会报错 mother2(list1); mother2(list2); //因为list3是其本身的类型,list4是其本身的父类所以不会报错 mother2(list3); mother2(list4); } /** * 定义一个方法 * 它的参数是ArrayList 但ArrayList的泛型是?super Number * 则ArrayList的泛型只能传入Number的本身或其的子类 * @param list */ private static void mother2(ArrayList<? super Number> list) { } /** * 定义一个方法 * 它的参数ArrayList的泛型 是 Number本身或其的子类 而Integer是继承于Number * @param list */ private static void mother1(ArrayList<? extends Number> list) { } }