------- android培训、java培训、期待与您交流! ----------
1.什么是泛型。
a) 泛型是1.5jdk的新特性指参数化类型的能力,主要提供给javac编译器使用的,可以定义带泛型类型的类或方法,随后编译器会用具体类型来替换它。
2.泛型的优点。
a) 能够在编译时而不是在运行时检测出错误。提高了软件的可靠性和可读性。
3.泛型的名称
a) 普通泛型称呼
i. ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语。
ii. 整个ArrayList<E>称为泛型类型,其中<E>称为类型变量或者类型参数。
iii. 整个ArrayList<Integer>称为参数化类型,其中的<Integer>称为类型参数化的实例或者实际类型参数。< >念typof,ArrayList称为元素类型。
b) 通配泛型称呼
i. 通配符 ?,表示任何一种对象类型。
1. 使用通配符可以引用其他各种参数的类型,通配符主要用作引用,可以调用与参数化无关的方法,不能调用参数有关的方法。
a) 例:
i. public static void printlnCollection(collection<object> cols){
for(Object obj : cols){
System.out.println(obj);}}
cols.add(“String”);//正确
cols = new HashSet<Date>();//错误
ii. public static void printlnCollection(collection<?> cols){
for(Object obj : cols){
System.out.println(obj);}}
cols.add(“String”);//错误
cols = new HashSet<Date>();//正确
Cols.size();//正确因为size()方法没有泛型。
ii. 限定通配符
1. 限定通配符的上边界,
a) Vector<? Extends Number> x = new vector<Integer>();//正确
b) Vector<? Extends Number> x = new vector<String>();//错误
c) 原因:? Extends Number指包含Number或者Number的子类
d) Integer属于Number的子类,而String不是
2. 限定符的下边界
a) Vector<? Super Integer> x = new vector<Number>();//正确
b) Vector<? Super String> x = new vector<Number>();//错误
c) 原因:? Super Integer指包含Integer的任意父类
d) Integer属于Number的子类,而String不是
3. 在限定通配符中可以用&符号,指定多边界
a) Public <? Extends Serialzable & cloneable> void method(){};
b) 这里就得用同时继承了Serialzable & cloneable的子类。
4.定义泛型。
a) 定义变量泛型。
i. 例:ArrayList<Integer> intList = new ArrayList<Integer>();
b) 定义方法泛型。
i. 在普通方法,构造方法和静态方法都可以定义泛型。
例:
1. public static <k,v> v getValue(k key){//定义多个类型参数时在括号用逗号
return map.get(key);} //分开
c) 定义类泛型。
如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型方式进行定义,也就是类型级别的泛型。
例:
public class GennericStack<E>{
Private java.util.ArrayList<E> list = new java.util.ArrayList<E>;
Public int getSize(){ return list.size();}//返回这个栈的元素个数
Public E peek(){ return list.get(getSize() - 1);}//返回这个栈的栈顶元素
Public void push(E obj){List.add(obj);}//添加元素
Public E pop(){//返回并删除这个栈的栈顶元素
E obj = List.get(getSize() - 1);
List.remove(getSize() - 1);
Return obj;}
Public boolean isEmpty(){//如果栈空则返回true;
Return List.isEmpty();
}
Class test{
Public static void main(String[] args){
GenericStack<String > Strck1 = new GenericStack<String>();
Stack1 .public(“lundon”);
Stack1 .public(“pai”);
}
}
类级别的泛型是根据引用该类各时指定的类型信息来参数化类型变量。
例:
GenericDao <String> dao = null;
New GennericDao <String> = 0;
5.原始类型和向后兼容。
1.参数化类型与原始类型的向后兼容性。
参数化类型可以引用一个原始类型的对象,编写警告:
Collection<String> c = new Vector();
原始类型可以引用一个参数类型对象,编译警告:
Collection c = new verctor<String>();
2.参数化类型不考虑类型参数的继承关系。
Vector<String> c = new Vector<Object>();//错误
Vector<Object> c = new Vector<String>();//也是错误
6.消除泛型和对泛型的限制。
1.消除泛型。
1.泛型是使用一种称为类型消除的方法来实现的。编译器使用泛型类型信息来编译 代码,但随后会消除它。因此,泛型信息在运行时是不可用的,这种方法可以使泛 型代码向后兼容使用元素类型的遗留代码。
泛型存在于编译时,一旦编译器确认泛型是安全使用的,就会将它转换为元素类型。
例:
ArrayList<String> list = new ArrayList<String>();
List.add(“asdasd”);
String state = List.get(0);
转换
ArrayList list = new ArrayList();
List.add(“asdasd”);
String state =(String) List.get(0);
2.泛型类被它的所有实例所共享。
例:
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<Integer> list1 = new ArrayList<Integer>();
System.out.println(List1 instanceof ArrayList);//答案为true
System.out.println(List2 instanceof ArrayList);//答案为true
System.out.println(List1 instanceof ArrayList<String>);//答案为false
因为ArrayList<String>并没有在jvm中存储为单独的一个类
2泛型的限制。
1.限制一:
泛型类型必须是引用类型,不能像int,double或char这样的基本类型来替换泛型类型。 例如
ArrayList <int> intList = new ArrayList<int>()语法是错误的.
ArrayList<Integer> intList = new ArrayList<Integer>()语法是正确的
2.限制二:
不能使用泛型类型参数创建实例。
E object = new E();
3.限制三:
不能使用泛型类型参数创建数组。
E[] elements = new E[capacity];
可以通过创建一个Object类型的数组,然后它的类型转换为E[]来规避这个规则。
E[] elements = (E[]) new Object[capacity];//可能出现ClassCastException异常。
4.限制四:
在静态环境下不允许类的参数是泛型类型,但可以单独定义泛型。
由于泛型类的所有实例都有相同的运行时类,所以泛型类的静态变量和方法是被它的所有实例锁共享的。因此在静态方法,数据域或者初始化语句中,为了类而引用泛型类型参数是非法的。
例
Public class Test<E>{
Public static void m(E o1){}
Public Static E o1;
Static {
E o2;}
}
5.限制五:
异常类最好不要泛型的。
i. 泛型类不能扩展java,lang,Throwable,但可以用方法的throws列表中,但不能用于catch子句中。
例
2. public static < T entends Exception > SayHello() throw T{
try{}
catch(Exception e)
{throw(T) e}
}//
7.通过反射来获取泛型
import java.util.*;
import java.lang.reflect.*;
class test3
{
public static void main(String[] args)throws Exception
{
ArrayList<Integer> inList = new ArrayList<Integer>();
inList.add(1);
//通过Class类来获取方法字节码。
Method applyMethod =
test3.class.getMethod("applyArrayList",ArrayList.class);
//再通过Method类来获取参数化类型
Type[] types = applyMethod.getGenericParameterTypes();
ParameterizedType ptype = (ParameterizedType)types[0];
System.out.println(ptype.getActualTypeArguments()[0]);
}
public static void applyArrayList(ArrayList<Integer> inList)
{
}
}