黑马程序员技术交流社区
标题:
反射与泛型的疑惑?
[打印本页]
作者:
抽烟男孩
时间:
2013-9-10 07:59
标题:
反射与泛型的疑惑?
本帖最后由 抽烟男孩 于 2013-9-12 13:38 编辑
<P>//通过反射给Integer泛型的ArrayList型集合list中添加String型变量“abc”。
public static void main(String[] args) throws Exception
{
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(3);
//通过反射添加“abc”
list.getClass().getMethod("add", Object.class).invoke(list, "abc");
System.out.println(list.get(0));//输出3,没问题</P>
<P>/*为什么以下语句没有问题*/
System.out.println(list.get(1));//输出“abc”,没问题
System.out.println(list.get(0).getClass());//输出3的类名没问题
/*为什么以下语句有问题*/
System.out.println(list.get(1).getClass());//输出“abc”的类名有问题
}</P>
复制代码
对比以下代码
//通过反射给String泛型的ArrayList型集合list中添加Integer型变量3。
public static void main(String[] args) throws Exception
{
ArrayList<String> list = new ArrayList<String>();
list.add("abc");
//通过反射添加3
list.getClass().getMethod("add", Object.class).invoke(list, new Integer(3));
System.out.println(list.get(0));//输出"abc",没问题
/*为什么以下语句有问题*/
System.out.println(list.get(1));//输出3,有问题
System.out.println(list.get(0).getClass());//输出“abc”的类名没问题
/*为什么以下语句有问题*/
System.out.println(list.get(1).getClass());//输出3的类名有问题
}
复制代码
作者:
黄文伯
时间:
2013-9-10 08:52
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
作者:
杨彬
时间:
2013-9-10 22:00
编译时候 如果有重载方法的调用,编译器要确定运行时候的到底调用哪一个重载方法
你现在ArrayList限定为<Integer> 这样 编译到最后一行的时候,会直接调用public void println(Object obj);
调用这个重载的原因是:编译的时候,ArrayList<Integer>的get方法返回的是Integer类型的数据
【注意 泛型信息是在编译完成之后被擦出的 编译的过程中是非常有用的】
【如果你不信 你就使用ctrl+左键 点击 println这个位置 就会自动跳到 PrintStream类的public void println(Object obj) 而不是其他的println重载方法】
所以 编译到最后一行的时候 get方法应该返回Integer类型的值,调用的就是println(Object obj) 但是你通过反射操作集合后存入的元素是String类型,当你再调用getClass()方法时JVM会尝试将String类型转换为Integer类型,但是转换不可行所以抛出异常
问题的根源就在于:
编译的时候,根据编译得到的实际参数【有泛型信息在里面】的类型来决定重载方法的调用 ---- 其一
println(String)和println(Object)同样接收数据 一个传入的是Integer 强转到String会报异常 另一个是String转换到Object 没有问题 。 -----其二
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2