泛型概述
泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制
泛型的好处:
把运行时期的问题提前到了编译期间
避免了强制类型转换
总结:
如果一个类的后面有<E>,表示这个类是一个泛型类
创建泛型类的对象时,必须要给这个泛型确定具体的数据类型
自定义泛型类
泛型的定义格式:
<类型>:指定一种类型的格式。
尖括号里面可以任意书写,按照变量的定义规则即可。一般只写一个字母。
比如:<E> <T> <Q> <M>
<类型1,类型2...>:指定多种类型的格式,多种类型之间用逗号隔开。
比如:<E,T> <Q,M> <K,V>
泛型类的定义格式:
格式:修饰符 class 类名 <类型> {}
范例:public class Generic<T> {}
此处的T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
泛型方法的定义格式:
格式:修饰符 <类型> 返回值类型方法名(类型 变量名) {}
范例:public <T> void show(T t) {}
package com.shengda.Demo3GenericitySummarize;
import java.util.ArrayList;
public class Demo4GenericityMethod2 {
public static void main(String[] args) {
ArrayList<String> list1 = addElement(new ArrayList<String>(), "a", "b", "c", "d");
System.out.println(list1);
ArrayList<Integer> list2 = addElement(new ArrayList<Integer>(),1,2,3,4);
System.out.println(list2);
}
public static <T> ArrayList<T> addElement(ArrayList<T> list,T t1,T t2,T t3,T t4) {
list.add(t1);
list.add(t2);
list.add(t3);
list.add(t4);
return list;
}
}
泛型接口
泛型接口的使用方式:
实现类也不给泛型
实现类确定具体的数据类型
泛型接口的定义格式:
格式:修饰符 interface 接口名 <类型> {}
范例:public interface Generic<T>{}
package com.shengda.Demo3GenericitySummarize;
public class Demo5GenericityInterface {
public static void main(String[] args) {
GenerictyImpl1<String> genericity = new GenerictyImpl1<>();
genericity.method("美羊羊");
GenerictyImpl2 generictyImpl2 = new GenerictyImpl2();
generictyImpl2.method(22);
}
}
interface Generic<T> {
public abstract void method(T e);
}
class GenerictyImpl2 implements Generic<Integer> {
@Override
public void method(Integer integer) {
System.out.println(integer);
}
}
class GenerictyImpl1<T> implements Generic<T>{
@Override
public void method(T e) {
System.out.println(e);
}
}
泛型通配符
类型通配符:<?>
ArrayList<?>:表示 元素类型未知的ArrayList,它的元素可以匹配任何的类型
但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
类型通配符上限:<?extends类型>
比如:ArrayList<?extends Number>:它表示的类型是Number或者其子类型
类型通配符下限:<?super类型>
代码中的实现
package com.shengda.Demo3GenericitySummarize;
import java.util.ArrayList;
public class Demo6Genericity {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<Number> list2 = new ArrayList<>();
ArrayList<Object> list3 = new ArrayList<>();
ArrayList<String> list4 = new ArrayList<>();
// printList(list1);
// printList(list4);
// method1(list1);
// method1(list2);
// method1(list3); // Object是Number的父类
// method2(list1); // Integer是Number的子类
// method2(list2);
// method2(list3);
}
// 表示传递过来集合的类型,可以是Number类型,也可以是Number所有的子类类型
private static void method1(ArrayList<? extends Number> list) { }
// 表示传递过来集合的类型,可以是Number类型,也可以是Number所有的父类类型
private static void method2(ArrayList<? super Number> list) { }
private static void printList(ArrayList<?> list) { }
}