A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ﹏゛心被伱牵 中级黑马   /  2012-10-24 08:11  /  1589 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

        昨天写代码发现一个问题,就是使用泛型虽然给我们带来了很大的安全问题,但是用了泛型我们是不是只能放置着一种类型的对象了,如下
                     TreeMap<Worker, String>  map=new TreeMap<Worker, String>();
                map.put(new Worker("黄强", 24), "北京");
                map.put(new Worker("小小", 21), "上海");
这是我们如果要放入其他对象,我们怎么办了,很纠结?

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

3 个回复

倒序浏览
本帖最后由 张忠豹 于 2012-10-24 12:12 编辑

张孝祥老师的java基础加强里面有讲到,这是我的代码笔记,希望对你有用……
  1. package staticImport.cn.itcast.day2;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.ParameterizedType;
  4. import java.lang.reflect.Type;
  5. import java.util.ArrayList;
  6. import java.util.Collection;
  7. import java.util.Date;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. import java.util.Set;
  11. import java.util.Vector;

  12. public class GenericTest {
  13. public static void main(String args[])throws Exception{
  14. ArrayList<String> list1 = new ArrayList<String>();
  15. list1.add("hello heima");
  16. ArrayList<Integer> list2 = new ArrayList<Integer>();
  17. //两个集合都是泛型参数实例化,但是返回的class字节码还是一样的
  18. System.out.println(list1.getClass()==list2.getClass());
  19. /**往list2中添加字符串:list2.add("abc");
  20. 由于ArrayList的泛型参数是Integer,如果存放字符串类型,在编译的时候是会报错的
  21. 所以要使用泛型来实现。因为编译生成的字节码会去掉泛型的信息,只要跳过编译器,就可以往某
  22. 非泛型集合中添加其它类型的数据.*/
  23. list2.getClass().getMethod("add", Object.class).invoke(list2, "abc");
  24. System.out.println(list2.get(0));

  25. /**通配符*/
  26. printCollection(list1);

  27. /**泛型----Map.key<key,value>*/
  28. HashMap<String, Integer> map = new HashMap<String,Integer>();
  29. map.put("zxx", 28);
  30. map.put("bxd", 27);
  31. map.put("yxf", 45);
  32. Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
  33. for(Map.Entry<String, Integer> entry:entrySet){
  34. System.out.println(entry.getKey() + ":" + entry.getValue());
  35. }

  36. /**泛型的语法定义和类型的推断*/
  37. // int x = add(3,3);//返回值为int类型
  38. Object x1 = add(3.5,3);//T的取值是取得两个参数类型的交集
  39. Object x2 = add(3.5,"abc");

  40. /**交换数组中两个元素的位置*/
  41. swap(new String[]{"abc","def","hij"},1,2);
  42. //swap(new int[]{1,2,3,4,5},2,3);这条语句会报错,泛型的实际类型,只能是对象类型、引用类型,不能是基本类型


  43. /**练习题*/
  44. Object obj = "abc";
  45. autoConvert(obj);
  46. //2
  47. // fillArray();
  48. copy1(new Vector<String>(),new String[10]);
  49. copy2(new Date[10],new String[10]);//类型推断为Object
  50. // copy1(new Vector<Date>(),new String[10]);//此处报错:已经为Vector的泛型指定了date类型,说明T就是Date,
  51. // 当类型参数被实例化之后,就具有传递性,T一定是Date

  52. /**类上面加泛型*/
  53. GenericDao<ReflectPoint> dao = new GenericDao<ReflectPoint>();
  54. dao.add(new ReflectPoint(3,3));
  55. ReflectPoint rp = dao.findById(1);


  56. /** 通过反射获取泛型的实际类型参数*/
  57. //Vector<Date> v1 = new Vector<Date>();这时通过V1对象是检查不出来Vector中泛型的类型的。只能通过方法
  58. Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
  59. Type type[] = applyMethod.getGenericParameterTypes();
  60. ParameterizedType pType = (ParameterizedType)type[0];
  61. System.out.println(pType.getRawType());
  62. System.out.println(pType.getActualTypeArguments()[0]);
  63. }
  64. public static <T> void applyVector(Vector<Date> v1){

  65. }
  66. private static <T> T autoConvert(Object obj){
  67. return (T)obj;
  68. }
  69. private static <T> void fillArray(T a[],T obj){
  70. for(int i=0;i<a.length;i++){
  71. a[i] = obj;
  72. }
  73. }
  74. private static <T> void copy1(Collection<T> src,T a[]){
  75. int len = src.size();
  76. // for()
  77. }
  78. private static <T> void copy2(T src[],T dest[]){

  79. }
  80. private static <T>/*声明泛型类型,在后面就可以使用了*/ void swap(T[] array,int i,int j){
  81. T temp ;
  82. temp = array[i];
  83. array[i] = array[j];
  84. array[j] = temp;
  85. }

  86. private static <T> T add(T t1,T t2){
  87. return null;
  88. }
  89. /*
  90. 通配符可以作为一个引用型变量来引用一个类型,但是引用别人以后,你不能拿着它去调用一个与
  91. 参数有关系的方法,就是与类型有关的方法你不能去调用 ,例如:add(E e);但是你可以调用
  92. size()方法,它与通配符引用的类型没有关系
  93. */
  94. private static void printCollection(Collection<?> collection) {
  95. for(Object obj:collection){
  96. System.out.println(obj);
  97. }
  98. }
  99. }
  100. class ReflectPoint{
  101. public ReflectPoint(int i, int j) {
  102. this.x = i;
  103. this.y = j;
  104. }
  105. private int x;
  106. public int y;
  107. }
  108. 连涉及到的笔记一块送到:
复制代码

评分

参与人数 1技术分 +1 收起 理由
谭立文 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 张忠豹 于 2012-10-24 12:14 编辑

泛型的作用
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass( )方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用add方法即可。
系统,不让我从doc中赋值文字,郁闷!粘到上面是一堆代码……
回复 使用道具 举报
你可以使用多重包装了, 先把Object 对象放进ArrayList里面, 再把ArrayList 放进Map 对象里面 或者把Map里面放Map , 这样就解决了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马