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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 奋斗2014 中级黑马   /  2014-7-1 15:09  /  1277 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

          先贴代码吧。        ArrayList<Integer> num1=new ArrayList<Integer>();        ArrayList<String> num2=new ArrayList<String>();
        System.out.println(num1.getClass()==num2.getClass());
        //num1.getClass().getMethod("add", String.class).invoke(num1, "abc");
        num1.getClass().getMethod("add", Object.class).invoke(num1, "abc");
        System.out.println(num1.get(0));
        如提,今天在复习张老师的泛型,因为张老师说过泛型在编译之后,就没有类型了,所以我们可以通过反射的方式,传进不同类型的值给泛型集合。但是我在传递的时候遇到这样一个问题,如上图,注释的那一行。getMethod()中,当我传入的类型是String.class的时候就报错,当我写Object.class的时候,又能运行,既然我最后传递的是String类型的,为啥前面会报错。求高手解答?


6 个回复

倒序浏览
你上面也说道了泛型在编译之后,就没有类型了,所以我们可以通过反射的方式,传进不同类型的值给泛型集合;
而你上面通过反射调用ArrayList的add()方法;里面指定的是String类型:
肯定会提示:
      Exception in thread "main" java.lang.NoSuchMethodException: java.util.ArrayList.add(java.lang.String)
这个异常:没有指定的方法的异常;

使用泛型,当编译后就没有类型了。这时ArrayList的add()有以下几种形式:
C:\Users\Administrator\Desktop\图像 3.jpg
就会发现,没有参数为String类型;所以就会报异常。而Object类型,肯定会有的,所以使用Object类型来当参数类型,这里用到了多态;
回复 使用道具 举报
补充:

图像 3.jpg (31.19 KB, 下载次数: 6)

上面的add()方法截图

上面的add()方法截图
回复 使用道具 举报

谢谢。不过我还是有一个疑问,String 不是Object的子类嘛,理论上来说应该可以的啊。
回复 使用道具 举报
这里报的异常是NoSuchMethodException所以跟泛型没关系,是getMethod方法报出的异常,模拟代码如下:
  1. public class Demo9 {
  2.         public static void main(String[] args) {
  3.                 Dog d = new Dog();
  4.                 // 错误代码示例
  5.                 try {
  6.                         d.getClass().getMethod("eat", String.class);
  7.                 } catch (NoSuchMethodException e) {
  8.                         System.out.println("找不到方法");// 会运行此句
  9.                 } catch (SecurityException e) {
  10.                         System.out.println("其他异常");
  11.                 } // 运行结果为打印找不到方法,这个异常是getMethod()方法抛出的,跟泛型没有关系,
  12.                         // 报此异常的原因是getMehod方法会严格按照定义方法时的方法签名找方法此例中Dog类只定义了Object参数的eat方法,
  13.                         // 故找不到String参数的eat方法

  14.                 // 相反,如果运行明确定义过的getMethod("eat", Object.class).invoke(d, "肉")就不会出现异常
  15.                 try {
  16.                         d.getClass().getMethod("eat", Object.class).invoke(d, "肉");//会打印吃肉
  17.                 } catch (Exception e) {
  18.                         e.printStackTrace();
  19.                 }
  20.         }

  21. }

  22. class Dog {
  23.         public void eat(Object str) {
  24.                 System.out.println("吃" + str);
  25.         }
  26.         //public void eat(String obj){
  27.         //}如果加上这个方法则上述就不会出现异常了

  28. }
复制代码

评分

参与人数 2黑马币 +2 收起 理由
奋斗2014 + 1
luheqi + 1 很给力!

查看全部评分

回复 使用道具 举报 1 0
奋斗2014 发表于 2014-7-2 09:43
谢谢。不过我还是有一个疑问,String 不是Object的子类嘛,理论上来说应该可以的啊。 ...

getMethod("add", String.class);方法是根据String的Class对象找对应的具有方法签名为add(String str)的方法的Method对象,假如类中还有方法签名为add(Object obj)的方法就必须用getMethod("add", Object.class)找,用getMethod("add", String.class)只能找到add(String str),add(Object obj)和add(String str)是两个不同的方法。
回复 使用道具 举报 1 0
EarlyHeart 发表于 2014-7-2 10:34
这里报的异常是NoSuchMethodException所以跟泛型没关系,是getMethod方法报出的异常,模拟代码如下:
...

谢谢!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马