黑马程序员技术交流社区

标题: 还是关于反射的问题 [打印本页]

作者: 张亚超    时间: 2015-4-15 13:18
标题: 还是关于反射的问题
importjava.util.*;
importjava.lang.reflect.*;
public class Test4{
      
      public static void main(String[] args)throws Exception {
           //定义一个容器,加入对象。
           List<Integer> list = newArrayList<Integer>();
           list.add(1);
           list.add(2);
           list.add(3);
           
           String str = "abc";
           //获取容器的add方法的字节码
           Method methodAdd =list.getClass().getMethod("add", int.class, Object.class);
           //用反射的方法调用add方法
           methodAdd.invoke(list, 1, str);
           //打印list容器中内容,验证。
           for(int i=0; i<list.size(); i++){
                 System.out.println(list.get(i));
           }   
      }   
}
Method methodAdd =list.getClass().getMethod("add", int.class, Object.class);这一行中的 Object.class换成 String.class 编译时能通过,但是运行的时候出现java.lang.NoSuchMethodException这个错误,为什么呢?


作者: sisel    时间: 2015-4-15 13:30
public boolean java.util.ArrayList.add(E) 方法签名不对
作者: sisel    时间: 2015-4-15 13:55
你这里应该使用getMethod("add", Object.class)
方法的反射信息如下:
public boolean java.util.ArrayList.add(java.lang.Object)
E arg0
class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
作者: 张亚超    时间: 2015-4-15 16:09
sisel 发表于 2015-4-15 13:55
你这里应该使用getMethod("add", Object.class)
方法的反射信息如下:
public boolean java.util.ArrayList ...

我用的第二个方法,在指定处插入那个,就是后面 那个 E是什么啊  我不知道 帮忙解释一下。。。
作者: waylent    时间: 2015-4-15 20:35
编译器在编译泛型的时候会进行类型擦除,就是在.class文件中把泛型去掉,并用相应的非泛型类型取代。对于没有指定边界的泛型参数(<T>、<E>),直接用Object代替。例如:
  1. public class Node<T> {

  2.     private T data;
  3.     private Node<T> next;

  4.     public Node(T data, Node<T> next) }
  5.         this.data = data;
  6.         this.next = next;
  7.     }

  8.     public T getData() { return data; }
  9.     // ...
  10. }
复制代码
编译后变为:
  1. public class Node {

  2.     private Object data;
  3.     private Node next;

  4.     public Node(Object data, Node next) {
  5.         this.data = data;
  6.         this.next = next;
  7.     }

  8.     public Object getData() { return data; }
  9.     // ...
  10. }
复制代码
所以,对于ArrayList编译后的字节码文件中的E:部分直接去掉,部分变成Object,就像上面演示的一样。




作者: 张亚超    时间: 2015-4-16 10:46
waylent 发表于 2015-4-15 20:35
编译器在编译泛型的时候会进行类型擦除,就是在.class文件中把泛型去掉,并用相应的非泛型类型取代。对于没 ...

是这样啊 ,谢谢啦




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2