黑马程序员技术交流社区

标题: 反射的一个细节问题始终困恼我啊! [打印本页]

作者: 黄云南    时间: 2012-3-29 23:43
标题: 反射的一个细节问题始终困恼我啊!
  1. import java.lang.reflect.Method;
  2. import java.util.ArrayList;
  3. import java.util.Collection;

  4. public class methodtest {
  5.         public static void main(String[] args) throws Exception, SecurityException{
  6.                         Collection<String> con= new ArrayList<String>();
  7.                         Method mt=Collection.class.getMethod("add", Object.class);

  8.                         System.out.println(mt.invoke(con,"add"));
  9.                         System.out.println(con);
  10.         }
  11.        
  12. }
复制代码
ArrayList的对象被Collection的引用指向,调用add()方法是调用了ArrayList中的方法这是多态的特性
我能理解为调用的其实是对象ArrayList中的add()方法。
可是反射时ArrayList和Collection中的add方法是不同的字节码。我们用得是Collection的add()方法的Method对象。
在用我上面的去理解就行不通了阿!!很迷惑!!谁指点下啊!!!
作者: 龚龙    时间: 2012-3-30 01:41
本帖最后由 龚龙 于 2012-3-30 17:53 编辑

Collcetion c1 = new ArrayList();
c1.add("测试1!");
System.out.println(c1.remove(0));        //这里打印出的是false ,因为调用的是Collection的remove 方法  ,子类当父类用,优先去父类里面的方法!
ArrayList c2 = new ArrayList();
c2.add("测试2!")
System.out.println(c2.remove(0));    //这里打印出的"测试2",调用的是ArrayList的remove 方法

所以,你开始的理解就行不通了........之前你那样写,其实还是调用的是Collection的add方法.
作者: 郑洋洋    时间: 2012-3-30 07:40
collection是接口,你要new一个collection对象,必须通过他的子类去new,所以没有必要去用多态性解释,java的多态就是通过接口的继承实现的。
反射中你因为不知道类具体有什么方法,所以你用的的collection的字节码,得到的也就是collection的方法。不冲突的
作者: 黄云南    时间: 2012-3-30 13:49
龚龙 发表于 2012-3-30 01:41
Collcetion c1 = new ArrayList();
c1.add("测试1!");
System.out.println(c.remove(0));        //这里打 ...

System.out.println(c.remove(0));我没看到c这个变量的声明啊!你的c是指who?
父类引用指向子类对象时,这是多态。调用方法时如果我没记错应该是子类有就用
子类的方法吧!Collection是个接口,方法都是抽象的怎么能调用它的方法呢?
作者: 黄云南    时间: 2012-3-30 14:03
本帖最后由 黄云南 于 2012-3-30 14:06 编辑

讨论着似乎有点明白过来了哈!说说我的猜想,大家说讨论对不对啊!反射时用得确实是Collection的add方法的字节码。
这个字节码的invoke方法在执行时要传一个Collection的对象和这个方法执行需要的参数进去。Collection是接口我们没法
创建对象,于是我们传了它的子类ArrayList的对象进去,这个方法去找add方法,发现有就执行了。所以是用了Collection
的add字节码调用的却是ArrayList的的对象的add方法!我理解的对不对啊!!!
作者: 龚龙    时间: 2012-3-30 17:59
黄云南 发表于 2012-3-30 14:03
讨论着似乎有点明白过来了哈!说说我的猜想,大家说讨论对不对啊!反射时用得确实是Collection的add方法的 ...

还是调用的Collection的add方法啊 ,没有调用它的子类 ArrayList的add方法,我那个例子不是说明了这么一问题了吗.刚那个c应该是c1,我改过来了.
作者: 黄云南    时间: 2012-3-30 22:21
龚龙 发表于 2012-3-30 17:59
还是调用的Collection的add方法啊 ,没有调用它的子类 ArrayList的add方法,我那个例子不是说明了这么一问 ...

c1用的还是ArrayList方法中的remove,那个方法中的remove参数是Object类型的,
那个0被自动装箱了Integer类型。集合中没有Integer类型的0这个元素删除就失败咯!
ArrayList中有两个remove方法,一个复写父类Collection的remove(Object obj),
一个以函数重载形式提供了按角标方式删除元素的remove(int index)。
谢谢讨论啊!!!
作者: 龚龙    时间: 2012-3-30 23:36
黄云南 发表于 2012-3-30 22:21
c1用的还是ArrayList方法中的remove,那个方法中的remove参数是Object类型的,
那个0被自动装箱了Integer ...

还是你是对的哈,没注意到这个自动装箱哈!!:L  以为还是用的父类方法了,果然还是new 的是谁,就首先调用谁的方法!




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