泛型简介
什么是泛型?
- 参化类型, 数是 JDK1.5 的新个性。(定义泛型时应用参数能够简略了解为形参), 例如 List<E>,Map<K,V>
- 编译时的一种类型,此类型仅仅在编译阶段无效,运行时有效. 例如 List<String> 在运行时 String 会被擦除, 最终零碎会认为都是 Object.
为什么要应用泛型?
泛型是进行类型设计或办法定义时的一种束缚标准, 基于此标准能够:
- 进步编程时灵活性(有点形象, 后续联合实例了解)。
- 进步程序运行时的性能。(在编译阶段解决一些运行时须要关注的问题,例如强转)
阐明: 泛型利用绝对比较简单, 难点在泛型类或办法的设计上, 通过这样的设计如何对现有类进行减法设计, 进步类或办法的通用性.
泛型利用类型
泛型定义时罕用形式有三种 (可参考 List<E>,Map<K,V) 等接口定义):
- 泛型类:class 类名 < 泛型,…>{}
- 泛型接口:interface 接口名 < 泛型,…>{}
- 泛型办法: < 泛型 > 办法返回值类型 办法名(形参){}
泛型类定义及利用
类泛型定义:(用于束缚类中办法参数和办法返回值类型)
class Array<T>{// 类泛型: 类名 < 泛型 >
Object[] array=new Object[10];
public void add(T t){}// 通过类泛型束缚办法参数类型
public T get(int i){// 通过类泛型束缚办法返回值类型
return (T)array[i];
}
}
泛型接口定义及利用
定义接口时指定泛型, 用于束缚接口办法参数类型以及办法返回值类型
interface Task<Param,Result>{// 思考 map 中的泛型 Map<K,V>
/**
* 此办法用于执行工作
* @param arg 其类型由泛型参数 Param 决定
* @return 其类型由泛型参数 result 决定
*/
Result execute(Param arg);
}
泛型接口利用实际
class ConvertTask implements Task<String,Integer>{
@Override
public Integer execute(String arg) {
// TODO Auto-generated method stub
return Integer.parseInt(arg);
}
}
泛型定义及利用
泛型办法中的泛型仅仅利用于以后办法,次要利用于一些静态方法,当然非静态方法也能够利用。
class ObjectFactory{
/** 泛型办法 */
public static <T>T newInstance(Class<T> cls){return (T)cls.newInstance();}
}
泛型利用通配符利用
无界线定通配符
泛型无界通配符应用”?”进行示意, 能够代表一种任意参数类型(实参类型)。个别利用于变量的定义。例如:Class<?> c1;
Class<?> c=Class.forName("java.util.Date");
上届界线定通配符
泛型上届限定符通过“<? extends 类型 >”形式进行实现,次要用于办法参数或办法的返回值类型,例如:
static void doPrint(List<? extends CharSequence> list){System.out.println(list);
}
下届限定通配符
泛型下届限定符通过“<? super 类型 >”形式进行实现,次要用于办法参数或办法的返回值类型,例如:
static void doPrint(Set<? super Integer> set){System.out.println(list);
}
泛型类型擦除实际剖析
泛型是编译时的一种类型,在运行时有效,运行时候都会变成 Object 类型,例如:
ArrayList<String> list = new ArrayList<String>();
list.add("A");
//list.add(100);// 间接不能够
// 通过反射将 100 增加到汇合
list.getClass().getMethod("add", Object.class).invoke(list, 100);
System.out.println(list);
总结(Summary)
本大节对泛型的定义,利用场景,利用类型以及泛型的类型擦出进行了剖析和实际,心愿在后续我的项目实际中对泛型有一个更好的意识。