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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张亚超 中级黑马   /  2015-4-15 13:18  /  1712 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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这个错误,为什么呢?

5 个回复

倒序浏览
public boolean java.util.ArrayList.add(E) 方法签名不对
回复 使用道具 举报
你这里应该使用getMethod("add", Object.class)
方法的反射信息如下:
public boolean java.util.ArrayList.add(java.lang.Object)
E arg0
class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
回复 使用道具 举报
sisel 发表于 2015-4-15 13:55
你这里应该使用getMethod("add", Object.class)
方法的反射信息如下:
public boolean java.util.ArrayList ...

我用的第二个方法,在指定处插入那个,就是后面 那个 E是什么啊  我不知道 帮忙解释一下。。。
回复 使用道具 举报
编译器在编译泛型的时候会进行类型擦除,就是在.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,就像上面演示的一样。



回复 使用道具 举报
waylent 发表于 2015-4-15 20:35
编译器在编译泛型的时候会进行类型擦除,就是在.class文件中把泛型去掉,并用相应的非泛型类型取代。对于没 ...

是这样啊 ,谢谢啦
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马