黑马程序员------Java的泛型(原理应用、自定义泛型)
来源:互联网 发布:梵高怎么得的精神 知乎 编辑:程序博客网 时间:2024/06/05 08:03
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
泛型
没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,
可以将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全,并
且从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制转换。
泛型是提供给Javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,
编译器编译带类型说明的集合时会去除掉“类型”信息,但程序运行效率不受影响,对于参数化的泛
型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信
息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据,例如,用反射得到集合,再
调用其add方法即可。
package com.lee.demo;import java.lang.reflect.Method;import java.util.ArrayList;public class GenericTest {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubArrayList<Integer> list = new ArrayList<Integer>();//list.add("abc");编译不能通过list.add(1);list.add(2);list.add(3);System.out.println(list.get(1));//利用反射,跳过编译器存入String对象Class clazz = list.getClass();Method addMethod = clazz.getMethod("add", Object.class);addMethod.invoke(list, "xyz");System.out.println(list.get(3));}}
泛型的通配符扩展应用
package com.lee.demo;import java.util.ArrayList;import java.util.Collection;public class GenericTest1 {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubArrayList<Integer> list = new ArrayList<Integer>();//list.add("abc");编译不能通过list.add(1);list.add(2);list.add(3);//sopCollection_0(list);编译失败sopCollection_1(list);}public static void sopCollection_0(Collection<Object> collection){//collection.add(1);由于无法确定?类型,编译失败System.out.println(collection.size());}public static void sopCollection_1(Collection<?> collection){//collection.add(1);由于无法确定?类型,编译失败System.out.println(collection.size());}}
总结:
使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,
可以调用与参数化无关的方法,不能调用与参数化有关的方法
限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
限定通配符的下边界:
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
提示:限定符总是包括自己。
泛型集合的综合应用:
package com.lee.demo;import java.util.HashMap;import java.util.Map;import java.util.Set;public class GenericTest2 {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubHashMap<String,Integer> maps = new HashMap<String, Integer>();maps.put("Tom", 12);maps.put("Kate", 15);maps.put("Hanmei", 13);Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();for(Map.Entry<String,Integer> me:entrySet){System.out.println(me.getKey()+":"+me.getValue());}}}
自定义泛型
自定义泛型方法
package com.lee.demo;public class GenericTest2 {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubNumber x = add(3,3.5);Object y = add(3,"das");swap(new String[]{"ad","lee","dsa"}, 1, 2);//只有引用类型才能作为泛型的实际参数。//swap(new int[]{1,5,8},1,2);编译失败swap(new Integer[]{1,5,8},1,2);}public static <T> T add(T x,T y){return null;}public static <T> void swap(T[] a,int i,int j){T tmp = a[i];a[i] = a[j];a[j] = tmp;}}
普通方法、构造方法和静态方法中都可以用泛型。编译器也不允许创建类型变量的数组。
也可以用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,但不
能存在catch子句中。
自定义泛型类
如果类的实例对象中的多处要用到同一个泛型参数,即这些地方引用的泛型方法要保持
同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型,
语法格式:
public class GenericDao <T>{
private T field1;
public void sava(T obj){}
public T getById(int id){}
}
类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如
GenericDao<String> dao = null;
new gennericDao<String>();
注意:
1.在泛型类型进行参数化时,类型参数的实例必须是引用类型,不嫩是基本类型。
2.当一个变量被声明为泛型时,只能被实例变量和方法调用,而不能被静态变量和静态方法调用。
因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数
通过反射获得泛型的实际类型参数
package com.lee.demo;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 GenericTest3 {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stubClass clazz = GenericTest3.class;Method applyMethod = (Method)clazz.getMethod("applyMethod",Vector.class);//得到参数类型Type[] types = applyMethod.getGenericParameterTypes();ParameterizedType pType = (ParameterizedType)types[0];//原始类型 class java.util.VectorSystem.out.println(pType.getRawType());//得到实际参数类型 class java.util.DateSystem.out.println(pType.getActualTypeArguments()[0]);}public static void applyMethod(Vector<Date> v1){}}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详情请查看:http://edu.csdn.net
- 黑马程序员------Java的泛型(原理应用、自定义泛型)
- 黑马程序员--自定义泛型(补充)
- 黑马程序员--泛型的基本应用
- 黑马程序员_日记53_泛型应用在自定义类的对象上
- 黑马程序员--泛型应用
- 黑马程序员——【Java】【高新技术】自定义泛型方法
- 黑马程序员,黑马论坛------(分享)Java 中的异常处理机制的简单原理和应用
- 黑马程序员——【Java反射学习】反射的应用:测试泛型的本质
- (黑马程序员)泛型限定原理和使用(一)
- 黑马程序员_泛型应用小结
- “黑马程序员—”泛型的应用小例子
- (黑马程序员)泛型的限定原理和使用(二)
- 黑马程序员——【Java】【高新技术】自定义泛型类 & 通过反射获得泛型的实际类型参数
- 黑马程序员Java知识回顾之集合_泛型自定义
- 黑马程序员_自定义泛型和序列化
- 黑马程序员---转载关于java泛型的详细介绍
- 黑马程序员--java高新技术--java5的泛型
- 黑马程序员——Java泛型通配符的总结
- C#中窗体使用Invoke和BeginInvoke详解
- Power Strings(kmp 重复子串)
- boost::checked_delete作用介绍
- excelDownload
- Android项目实战--手机卫士18--读取用户的短信内容以及短信备份
- 黑马程序员------Java的泛型(原理应用、自定义泛型)
- log4j:ERROR Could not instantiate class [org.apache.hadoop.hive.shims.HiveEventCounter].
- PowerDesigner 学习及使用
- Delphi JSON 天气预报
- 线程同步与互斥
- 温度PID的整定过程
- multipart/form-data和application/x-www-form-urlencoded
- Redis实战之征服 Redis + Jedis + Spring (三)
- 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。 //求总共有多少总跳法,并分析算法的时间复杂度