黑马程序员-泛型
2013-09-24 15:58
218 查看
泛型:安全机制。编译过后会被擦除。
思考题不会报错。因为参数化类型可以和原始类型是兼容的。
好处:
1,将运行时期出现的ClassCastException,转移到了编译时期。方便与程序员解决问题。
2,避免强制转换。
泛型的使用:
格式:通过<>来定义要操作的引用数据类型。读作typeof
使用java提供的对象时,什么时候使用泛型呢?
通常集合常见,见到<>就需要定义泛型。
泛型类:当类中操作的引用数据类型不确定的时候。早期用Object扩展,现在用泛型。
泛型方法:泛型类定义泛型,在整个类中有效。如果方法被使用,那么泛型类的对象明确要操作的具体类型后,所有的操作就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。(定义在返回值前)
泛型在方法上定义只在方法中有效。不同方法的泛型互不干扰。
泛型类和泛型方法不冲突。
静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
泛型的限定:
<?>通配符:只能调用对象中与参数化无关的方法。
<? 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数组呢?
异常中泛型的应用:
通过反射获得参数的实际类型参数:
思考题不会报错。因为参数化类型可以和原始类型是兼容的。
好处:
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){ 不是重载,去类型化。 } */ }
相关文章推荐
- 黑马程序员——17,集合,TreeSet,二叉树,泛型
- 黑马程序员_泛型(Generic)
- 黑马程序员-JAVASE入门(泛型)
- 黑马程序员——java中泛型的应用
- 黑马程序员_泛型
- 黑马程序员——(八)泛型
- 黑马程序员-------Java笔记--------怎么越过泛型检查
- 黑马程序员--第十五天:泛型
- 黑马程序员—JAVA高新技术_泛型
- 黑马程序员:Java基础总结----泛型
- 黑马程序员java笔记之五-----泛型
- 黑马程序员---泛型
- 黑马程序员-----集合框架(Map和泛型)
- 黑马程序员:Java基础总结----泛型(高级)
- 黑马程序员 知识点总结-Java泛型
- 黑马程序员_泛型小结
- 黑马程序员---Java基础加强---JDK1.5新特性:泛型
- 黑马程序员——java高新技术(新特性、反射、泛型)
- 黑马程序员_高新技术3(JavaBean复杂操作,注解Annotation,泛型应用Generic)
- 黑马程序员--Java基础加强--14.利用反射操作泛型III【解析关于泛型类型的细节信息的获取方法】【Method与泛型相关的方法】【个人总结】