您的位置:首页 > 职场人生

黑马程序员-泛型

2013-09-24 15:58 218 查看
泛型:安全机制。编译过后会被擦除。



 思考题不会报错。因为参数化类型可以和原始类型是兼容的。

好处:

1,将运行时期出现的ClassCastException,转移到了编译时期。方便与程序员解决问题。

2,避免强制转换。

泛型的使用:

格式:通过<>来定义要操作的引用数据类型。读作typeof

使用java提供的对象时,什么时候使用泛型呢?

通常集合常见,见到<>就需要定义泛型。

泛型类:当类中操作的引用数据类型不确定的时候。早期用Object扩展,现在用泛型。

class Utils<Q>{
private Q q;
public  void setObject(Q q){
this.q=q;
}
public Q getObject(){
return q;
}
}

泛型方法:泛型类定义泛型,在整个类中有效。如果方法被使用,那么泛型类的对象明确要操作的具体类型后,所有的操作就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。(定义在返回值前)

class Demo{
public   <T>void  show(T t){
}
public   <Q>void   print(Q q){
}
}

泛型在方法上定义只在方法中有效。不同方法的泛型互不干扰。

泛型类和泛型方法不冲突。

class Demo<T>{
public   void  show(T t){
}
public   <Q>void   print(Q q){
}
}

静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。

泛型接口:
interface Inter<T>{
void  show(T t);
}
class InterImpl<T> implements Inter<T>{
public void show(T t){
}
}
class InterImpl implements Inter<String>{
public void show(String t){
}
}

泛型的限定:

<?>通配符:只能调用对象中与参数化无关的方法。

<? extends E>  接收E和E的子类,上限。

<?  super   E>  接收E和E的父类,下限。

跳过泛型的检查:通过反射。

ArrayList<String>  al = new ArrayList<String>();

al.getClass().getMethod("add",Object.calss).invoke(al,5);

此时可以将5存入集合。

注意:只有引用类型才能作为泛型方法的实际参数,对于add方法,使用基本类型的数据测试文有问题,这是因为自动装箱和拆箱,下面swa(new int[ ]{1,2,3},1,2);会报告编译错误,因为编译器不会把基本数据类型的int自动拆箱和装箱。因为new int[ ]本身就已经是一个对象了。你想要的可能就是int数组呢?

public class Text {

public static void main(String[] args) {
int[] arr=new int[]{1,3,4,5};
int n=5;
String[] s = new String[]{"haha","hehe","heihei"};
//交换数组中字符串的位置。
swap(s,1,2);
//swap(new int[]{1,2,3},3,5);编译错误
for(String s1:s){
System.out.println(s1);
}
swa(n);

}
public static  <T> void swap(T[] a,int i,int j){
T tmp=a[i];
a[i]=a[j];
a[j]=tmp;

}
public static <T> void swa(T a){
System.out.println(a);
}

}

 异常中泛型的应用:

private static <T extends Exception> sayHello() throws T
{
try{
}
catch(T e){
throw <T>  e
}
}




通过反射获得参数的实际类型参数:

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Vector;

public class GenericTest {

public static void main(String[] args)throws Exception {
Vector<Date> v1=new Vector<Date>();
Method applyMethod=GenericTest.class.getMethod("applyVector",Vector.class);
Type[] types=applyMethod.getGenericParameterTypes();
ParameterizedType pType=(ParameterizedType)types[0];
System.out.println(pType.getRawType());//返回声明此类的原始类型的类或接口Vector
System.out.println(pType.getActualTypeArguments()[0]);//返回此类型实际参数化的类型,可能有多个,比如map集合。Date

}
public static void applyVector(Vector<Date> v1){

}
/*public static void applyVector(Vector<String> v1){
不是重载,去类型化。
}
*/
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: