什么是泛型
泛型的本质是参数化类型,也就是说所操作的 数据类型 被指定为一个参数
泛型有什么优势
泛型完成的功能,Object类型也能完成,但是使用泛型可以更加方便,如泛型不需要类型转换、泛型在编译期间就能发现类型异常等
类型通配符
- 使用?代替具体的类型参数
- 通过super或extends来限定通配符范围
List<? extends T>和List <? super T>之间有什么区别 ?
考察的是 限定通配符 与 非限定通配符 的问题;
其两者都是限定通配符,List<? extends T> 可以接受任何继承自T类型的元素,而 List<? super T> 可以接受任何T的父类元素。例如List<? extends Number>可以接受List或List;
非限定通配符用 < ? > 表示,可以用任意类型来替代。
泛型类、泛型接口、泛型方法简单用例
泛型类
/**
* @Author Snail
* @Describe 泛型的测试用例
* @CreateTime 2019/11/28
*/
public class GenericTest<T> {
private T t;
public GenericTest(T t) {
this.t = t;
}
public void showType() {
System.out.println("T的实际类型是:" + t.getClass().getName());
}
public static void main(String[] args) {
GenericTest<Integer> gen = new GenericTest(1);
gen.showType();//T的实际类型是:java.lang.Integer
System.out.println(" ====================== ");
//定义泛型类Generic的一个String的版本
GenericTest<String> strObj = new GenericTest("Hello Gen!");
strObj.showType();//T的实际类型是:java.lang.String
}
}
在上面的例子中,没有限制 T 的范围,T 可以是任意的类型。
如果需要限制 T 类型,其 T 符合单继承多实现(继承的类在前,实现的接口在后)的规则,写法如下:
public class GenericTest<T extends Number & Serializable > {
//表达的意思:限制 T 必须是类 Number 和接口 Serializable 的共同子类
...
}
泛型接口
interface GenericInterface<T>{
public T get();
}
/**
* @Author Snail
* @Describe 泛型接口测试
* @CreateTime 2019/11/29
*/
public class GenericInterfaceTest implements GenericInterface<String>{
@Override
public String get() {
return "string";
}
public static void main(String[] args) {
GenericInterfaceTest genericInterfaceTest = new GenericInterfaceTest();
System.out.println(genericInterfaceTest.get());
}
}
泛型方法
泛型方法在调用时可以接收不同类型的参数,在方法内部可以根据不同的类型做出不同的处理。
/**
* 泛型方法:合并字符串或合计数字
*
* @param arr
* @param <E> 类型参数声明部分(由尖括号分隔)
* @return
*/
<E> E mergerOrCount(E[] arr){
Integer count=0;
String merger="";
for(E e:arr){
String className = e.getClass().getName();
if (className.equals(String.class.getName())) {
merger+=(String) e;
}else if(className.equals(Integer.class.getName())){
count += (Integer) e;
}
}
return (E)(count==0?merger:count);
}
@Test
public void genericMethodParams() {
Integer integerRes = mergerOrCount(new Integer[]{1, 2, 3, 4});
Assert.assertEquals(new Integer(10),integerRes);
String strStr = mergerOrCount(new String[]{"a", "bb", "ccc"});
Assert.assertEquals("abbccc",strStr);
}