定义格式:
修饰符 class 类名<泛型>{}
例如:
public class GenericClass<E> { private E name; public GenericClass() { } public GenericClass(E name) { this.name = name; } public E getName() { return name; } public void setName(E name) { this.name = name; } }
使用泛型:在创建对象的时候确定泛型
public class Demo01 { public static void main(String[] args) { GenericClass<String> genericClass = new GenericClass<>(); genericClass.setName("创建对象即确定泛型"); String name = genericClass.getName(); } }
定义格式:
修饰符 <泛型> 返回值类型 方法名(参数){}
例如:
public class GenericMethod { //定义一个含有泛型的方法 public <M> void method01(M m) { System.out.println(m); } //定义一个含有泛型的静态方法 public static <S> void method02(S s) { System.out.println(s); } }
使用格式:调用方法时,确定泛型的类型
public class Demo02 { public static void main(String[] args) { GenericMethod gm = new GenericMethod(); gm.method01("字符串"); gm.method01(123); gm.method01(false); GenericMethod.method02("静态方法"); GenericMethod.method02(111); } }
定义格式:
修饰符 interface 接口名<泛型>{}
例如:
public interface GenericInterface<I> { public abstract void method(I i); }
使用格式:
例如:
public class GennericInterfaceImpl1 implements GenericInterface<String> { @Override public void method(String s) { System.out.println(s); } }
例如:
/** * 含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型。 * 就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型 */ public class GennericInterfaceImpl2<I> implements GenericInterface<I> { @Override public void method(I i) { System.out.println(i); } }
public class Demo03 { public static void main(String[] args) { GennericInterfaceImpl1 impl1 = new GennericInterfaceImpl1(); impl1.method("字符串"); GennericInterfaceImpl2<Integer> impl2 = new GennericInterfaceImpl2<>(); impl2.method(100); GennericInterfaceImpl2<String> impl3 = new GennericInterfaceImpl2<>(); impl3.method("创建对象时确定泛型类型"); } }
泛型的通配符:不知道什么类型来接收的时候,此时可以使用?,?表示未知通配符。
例如:泛型没有继承概念
/** * 泛型的通配符: * ?:代表任意的数据类型 * 使用方式: * 不能创建对象使用 * 只能作为方法的参数使用 */ public class Demo04Generic { public static void main(String[] args) { ArrayList<Integer> list01 = new ArrayList<>(); list01.add(10); list01.add(20); ArrayList<String> list02 = new ArrayList<>(); list02.add("a"); list02.add("b"); printArray(list01); printArray(list02); } /* 定义一个方法,能遍历所有类型的ArrayList集合 此时我们不知道ArrayList集合使用什么数据类型,就可以使用泛型的通配符<?>来接收数据类型 注意: 泛型没有继承概念(即方法入参不能用ArrayList<Object>来接收) */ public static void printArray(ArrayList<?> arrayList){ for (Object i : arrayList) { System.out.println(i); } } }
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置,但是在JAVA的泛型中可以指定一个泛型的上限和下限。
类型名称<? extends 类名> 对象名称
只能接收该类型及其子类
类型名称<? super 类名> 对象名称
只能接收该类型及其父类
比如:现已知Object类,String类,Number类,Integer类,其中Number是Integer的父类
public class Demo05Generic { public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<>(); Collection<String> list2 = new ArrayList<>(); Collection<Number> list3 = new ArrayList<>(); Collection<Object> list4 = new ArrayList<>(); getElement1(list1); getElement1(list2);//报错 getElement1(list3); getElement1(list4);//报错 getElement2(list1);//报错 getElement2(list2);//报错 getElement2(list3); getElement2(list4); } // 泛型的上限:此时的泛型?,必须是Number类型或其子类 public static void getElement1(Collection<? extends Number> coll){} // 泛型的下限:此时的泛型?,必须是Number类型或其父类 public static void getElement2(Collection<? super Number> coll){} }