Java泛型是从JDK5中新加入的一个新特性。泛型提供了编译时类型安全检测机制,该机制可以在编译时检测到非法的类型。
定义泛型类:
public class GenericClass<E> { private E name; public E getName() { return name; } public void setName(E name) { this.name = name; } }
测试:
public class DemoGenericClassTest { public static void main(String[] args) { GenericClass<Integer> gc = new GenericClass<>(); gc.setName(1); Integer name = gc.getName(); System.out.println(name); } }
注:
<E1,E2,E3>
public GenericClass(){}
,而不是public GenericClass<E>{}
语法:
修饰符 interface 接口名<代表泛型的变量>{}
定义含有泛型的接口:
/** * 定义含有泛型的接口 */ public interface GenericInterface<I> { public abstract void method(I i); }
使用含有泛型接口的第一种方式
创建类实现含有泛型的接口:
/** 含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型 */ public class GenericInterfaceImpl1 implements GenericInterface<String> { @Override public void method(String s) { System.out.println(s); } }
测试含有泛型的接口:
public class DemoGenericInterfaceTest { public static void main(String[] args) { GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1(); gi1.method("你好"); } }
使用含有泛型接口的第二种方式
创建类实现接口:
/** * 含有泛型的接口第二种使用方式:接口使用什么类型,实现类就使用什么泛型,类跟着接口走 * 就相当于定义一个含有泛型的类,创建对象的时候确定泛型的类型 */ public class GenericInterfaceImpl2<I> implements GenericInterface<I> { @Override public void method(I i) { System.out.println(i); } }
测试:
public class DemoGenericInterfaceTest { public static void main(String[] args) { GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>(); gi2.method(10); } }
语法:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){}
定义泛型方法:
public class GenericMethod { public <M> void method1(M m) { System.out.println(m); } public static <S> void method2(S s) { System.out.println(s); } }
测试如下:
public class DemoGenericMethodTest { public static void main(String[] args) { //创建GenericMethod对象 GenericMethod gm = new GenericMethod(); gm.method1(10); gm.method1("abc"); gm.method1(1.34); //使用类名直接调用静态方法 GenericMethod.method2("def"); GenericMethod.method2(123); } }
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>
表示,一旦使用泛型的通配符,只能使用Object类中的共性方法,集合元素自身方法无法使用。
当不知道使用什么类型来接收的时候,此时可以使用?
,?
表示未知通配符。
/** * 泛型的通配符 * ?: 代表任意的数据类型 * 使用方式: * 不能创建对象使用 * 只能作为方法的参数使用 */ public class DemoGeneric { public static void main(String[] args) { ArrayList<Integer> list01 = new ArrayList<>(); list01.add(1); list01.add(2); ArrayList<String> list02 = new ArrayList<>(); list02.add("a"); list02.add("b"); printArray(list01); printArray(list02); } public static void printArray(ArrayList<?> list) { Iterator<?> it = list.iterator(); while (it.hasNext()) { Object o = it.next(); System.out.println(o); } } }
泛型的上限:
类型名称<? extends 类> 对象名称
:只能接收该类型及其子类泛型的下限:
类型名称<? super 类> 对象名称
:只能接收该类型及其父类型import java.util.ArrayList; import java.util.Collection; /** * 泛型的上限限定: ? extends E 使用的泛型只能是E类型的子类/本身 * 泛型的下限限定: ? super E 使用的泛型只能是E类型的父类/本身 */ public class TestGeneric { 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); } //泛型的上限 public static void getElement1(Collection<? extends Number> coll) { } //泛型的下限 public static void getElement2(Collection<? super Number> coll) { } }