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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 梁豹新 初级黑马   /  2012-6-20 13:03  /  2131 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package cn.itcast.day2;

import java.util.ArrayList;

public class GenericDemo {

        public static void main(String[] args)throws Exception {
               
                                               
                       
                        //System.out.println(collcetion2.getClass()==collcetion3.getClass());//表明字节码中没有泛型信息了
                       
                        //在collcetion2集合中加入Integer类型元素,可以通过反射。直接不是能添加的。
                       
       
                        ArrayList<String> collcetion2 = new ArrayList<String>();
                        collcetion2.add("abc");
                        collcetion2.getClass().getMethod("add", Object.class).invoke(collcetion2,78);
                       
                        System.out.println(collcetion2.get(0));
                        System.out.println(collcetion2.get(1));
                       
                       
                        ArrayList<Integer> collcetion3 = new ArrayList<Integer>();
                        collcetion3.add(12345);
                        collcetion3.getClass().getMethod("add", Object.class).invoke(collcetion3,"abcd");
                       
                        System.out.println(collcetion3.get(0));
                        System.out.println(collcetion3.get(1));
                       
                        ArrayList collection=collcetion3.getClass().newInstance();
                        collection.add("icast");
                        System.out.println(collection.get(0));               
                }
}

视频中只讲到在 Integer 泛型集合中通过反射可以存入String类型:
                        ArrayList<Integer> collcetion3 = new ArrayList<Integer>();
                        collcetion3.add(12345);
                        collcetion3.getClass().getMethod("add", Object.class).invoke(collcetion3,"abcd");
                       
                        System.out.println(collcetion3.get(0));
                        System.out.println(collcetion3.get(1));

但我试了往String 泛型集合中通过反射存入Integer类型是出错:
                        ArrayList<String> collcetion2 = new ArrayList<String>();
                        collcetion2.add("abc");
                        collcetion2.getClass().getMethod("add", Object.class).invoke(collcetion2,78);
                       
                        System.out.println(collcetion2.get(0));
                        System.out.println(collcetion2.get(1));

实在想不出为什么?

还有就是下面两种方法的区别:
                        方法一:
                        ArrayList<Integer> collcetion3 = new ArrayList<Integer>();
                        collcetion3.add(12345);
                        collcetion3.getClass().getMethod("add", Object.class).invoke(collcetion3,"abcd");
                       
                        System.out.println(collcetion3.get(0));
                        System.out.println(collcetion3.get(1));
                       
                        方法二:
                        ArrayList collection=collcetion3.getClass().newInstance();
                        collection.add("icast");
                        System.out.println(collection.get(0));       


5 个回复

倒序浏览
本帖最后由 闾丘日月 于 2012-6-20 14:42 编辑

楼主这个问题太难了,我一下子没看懂,先占个位置研究一下,还有等高手解答,搞懂了就回复你
我再提一个问题,
我将代码修改为
                        ArrayList<String[]> collcetion2 = new ArrayList<String[]>();   
                        collcetion2.getClass().getMethod("add", Object.class).invoke(collcetion2,78);                 
                        System.out.println(collcetion2.get(0));
虚拟机都是可以正确执行的,或者说泛型里面我任意填一个类型,只要不是String或者基本类型,都是可以正确的被转换的。
也就是说78这么一个整数或者整数对象,除了不能被转化为String类型以外,几乎所有的类型它都能转换过去。。。。
显然这是个荒谬的结论,那么到底是为什么》?
回复 使用道具 举报
本帖最后由 黑马_张佳超 于 2012-6-20 14:23 编辑

将Integer类型数据通过反射添加到String类型的集合中,和把String类型的数据通过反射添加到Integer类型的集合中实现过程是一样的。
只是当Integer类型的数据从String类型的集合中取出时出的问题。
错误提示为:不能将Integer类型数据投射为String类型数据。
也就是:System.out.println(collcetion2.get(1)) --> System.out.println(String.valueOf(collecetion2.get(1)))
下边两种方法的区别:
方法一:ArrayList类的实例通过调用getClass()方法获取ArrayList类型的Class对象。getClass()方法定义在Object类中,用来获取本实例对象的类信息,包括字段和方法等内容信息。
也就是对象实例通过获得对象类信息来完成该实例对象方法的调用的过程就是反射的过程
方法二:通过ArrayList类型的实例先获取到ArrayList的Class信息,通过Class中的newInstance()重新创建ArrayList类型的对象。
回复 使用道具 举报
先回答第一个问题

通过反射已经将数据存进去了,你的问题可能是因为限定了<String>泛型,所以取不出来
  1.                 ArrayList<String> collcetion2 = new ArrayList<String>();               
  2.                 collcetion2.add("abc");
  3.                 collcetion2.getClass().getMethod("add", Object.class).invoke(collcetion2, 78);
  4.                 System.out.println("1");

  5.                 System.out.println(collcetion2.get(0));
  6.                 System.out.println(collcetion2.get(1));  //可以在这里加断点调试下,collcetion2里面果然有一个intger呵呵.
复制代码
如果你用一个ArrayList collection=collcetion2;在这样的情况下,调用
  System.out.println(collection.get(0));   
  System.out.println(collection.get(1));
都没有了ArrayList<String> collcetion2 的类型限定,所以你的78是可以输出出来的

第二个问题包含多个内容
方法一:
                        ArrayList<Integer> collcetion3 = new ArrayList<Integer>();  常规的声明方法
collcetion3.add(12345);
                        collcetion3.getClass().getMethod("add", Object.class).invoke(collcetion3,"abcd");  这里通过反射调用了add方法
System.out.println(collcetion3.get(0));
                        System.out.println(collcetion3.get(1));
                        
                        方法二:
                        ArrayList collection=collcetion3.getClass().newInstance(); 这里通过反射找到了类,直接调用反射的构造方法
collection.add("icast"); 常规的调用方法
                        System.out.println(collection.get(0));


其实你可以这样写
ArrayList<Integer> collcetion3 = new ArrayList<Integer>();
ArrayList collection=collcetion3.getClass().newInstance();
collcetion.getClass().getMethod("add", Object.class).invoke(collcetion,"abcd");  
全用反射来玩呵呵

点评

请你看看我在2楼提的问题能不能解决?我也加了泛型限定,但是可以正确输出  发表于 2012-6-21 02:14
回复 使用道具 举报
关于你最后的两个问题,这两个方法根本就没有联系  collcetion3.getClass().getMethod("add", Object.class).invoke(collcetion3,"abcd"); 这个只是利用发射来对collection3调用add方法,而你下面那个 ArrayList collection=collcetion3.getClass().newInstance(); 这个是调用了Class类的newInstance方法来构造一个ArrayList .class的实例对象,两者没有什么直接联系  请楼主看视频的时候 多看几遍 就行了 然后多动手试一下 再顺便查一下文档你就清楚了 希望能帮到你
回复 使用道具 举报
李天甲 发表于 2012-6-20 14:13
先回答第一个问题

通过反射已经将数据存进去了,你的问题可能是因为限定了泛型,所以取不出来如果你用一个Ar ...

谢谢了,终于明白那里错了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马