黑马程序员技术交流社区

标题: 谁想要技术分的,赶紧都来啊。过了这个村,可没这个店! [打印本页]

作者: 牛杨    时间: 2012-9-19 23:37
标题: 谁想要技术分的,赶紧都来啊。过了这个村,可没这个店!
本帖最后由 牛杨 于 2012-9-21 20:16 编辑

先解决这个问题,小弟也帮你申请技术分   {:soso_e113:} 。
可变参数类型的Class实例是什么啊?
张老师说:只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[],void…  。
我知道int[]的Class对象时 int[].class ;
void 的是 void.class 。
那一个可变参数的class对象实例怎么表示呢?
比如 :
   public  void add(int ... args)
   {
         ………………
   }  
这里面的 int ... args的Cass对象实例怎么表示呢?
关于这个问题:
1、如果一个类里面有一个可变参数的方法。我们通过这个这个类的字节码Class对象实例的getMethod方法怎么获取到这个具有可变参数的方法呢?
2、如果获取到了这个方法,也即有一个Method对象代表了这个具有可变参数的方法。那么怎么通过这个Method对象的invoke方法来调用这个方法呢?


希望走过路过的高手能帮俺解决下啊,小弟帮你申请技术分哦!
作者: 牛杨    时间: 2012-9-19 23:52
{:soso_e136:} 真悲催! 唉…… 连一个捧场的都没
作者: 叶征东    时间: 2012-9-19 23:55
本帖最后由 叶征东 于 2012-9-20 00:00 编辑

........................................

作者: 严海荣    时间: 2012-9-19 23:56
{:soso__7292164335633564309_1:}捧个场,水平有限,无能为力。
作者: 夏天    时间: 2012-9-19 23:58
捧场,刚看到反射
作者: 牛杨    时间: 2012-9-19 23:59
叶征东 发表于 2012-9-19 23:55
将int替换成Class,可以么?
我也不太懂.

这个和泛型貌似没有太大关系吧。 我曾经试了试 int[] .class   运行出问题了。没有结果。
作者: 牛杨    时间: 2012-9-20 00:01
{:soso_e183:}  谢谢各位老少爷们捧场了 。
作者: 牛杨    时间: 2012-9-20 00:03
夏诗瑶 发表于 2012-9-19 23:58
捧场,刚看到反射

我也是啊, 我个人认为: 这个反射 学着也好懂好理解。就是综合用就挂了。就像这个。 共同进步哦
作者: 夏天    时间: 2012-9-20 00:09
呵呵,早点睡吧,我明天还要上课,加油!!
作者: 王陶成    时间: 2012-9-20 00:12
可变参数不是数组过来的吗,可不可以当数组获取一下
作者: 牛杨    时间: 2012-9-20 00:19
王陶成 发表于 2012-9-20 00:12
可变参数不是数组过来的吗,可不可以当数组获取一下

话虽这么说,我想尽了办法。弄个 int[].class 也试试了。结果还是不行
作者: 寇龙飞    时间: 2012-9-20 04:26
11楼正解哦。按照知识逻辑、跟着感觉走,就是用int[].class,不知道你怎么用的?贴你的代码。

这是我的代码:
  1. package com.itheima.test;

  2. public class SomeArgsDemo {

  3.         public static void main(String[] args) throws Exception {
  4.                
  5.                 System.out.println(SomeArgs.class.getMethod("println", int[].class));
  6.                 SomeArgs someArgs = new SomeArgs();
  7.                 int[] arr = new int[]{10,10};
  8.                 SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, arr);
  9.         }
  10. }

  11. class SomeArgs {
  12.         public void println(int... args) {
  13.                 System.out.println("int...与int[]是一样滴,本质还是int[],int...用起来更简便");
  14.         }
  15. }
复制代码
打印结果为:
  1. public void com.itheima.test.SomeArgs.println(int[])
  2. int...与int[]是一样滴,本质还是int[],int...用起来更简便
复制代码

作者: 何小红    时间: 2012-9-20 06:15
多看两遍视频,多写点代码,基础不牢,帮不上忙,抱歉啊
作者: 彭润生    时间: 2012-9-20 07:04
本帖最后由 彭润生 于 2012-9-20 07:05 编辑
  1. public class ReflectDemo3 {

  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args)throws Exception {
  6. String str1 = "hdskjf";
  7. //Method strMetCharAt = String.class.getMethod("charAt",int.class);
  8. //System.out.println(strMetCharAt.invoke(str1,5));//如果invoke第一个参数是null则是调用静态方法
  9. Method strMetRep = String.class.getMethod("replace", char.class,char.class);//这儿是的
  10. System.out.println(strMetRep.invoke(str1,new Object[]{'h','a'}));//这儿也可改成这样的列表形式
  11. }

  12. }
复制代码

作者: zhaosenyang    时间: 2012-9-20 07:50
本帖最后由 赵森羊 于 2012-9-20 07:51 编辑

给你写个列子:
  1. package cn.itcast.day02;

  2. import java.lang.reflect.Method;
  3. class ReflexPoint{
  4.         public int add(int...args ){
  5.                 int sum=args[0];
  6.                 for (int i = 0; i < args.length; i++) {
  7.                         sum+=args[i];
  8.                 }
  9.                 return sum;
  10.         }
  11. }
  12. public class ReflexTest {
  13.         public static void main(String[] args) throws Exception {
  14.                 Class cl=Class.forName("cn.itcast.day02.ReflexPoint");
  15.                 Object obj=cl.newInstance();
  16.                 Method me=cl.getMethod("add",int[].class);//1:获取add方法,int...args的Class实例就是int[].class</span>
  17.                 System.out.println(me.invoke(obj, new int[]{1,2,3}));//2:调用:invoke(obj, new int[]{1,2,3} ,这里不能直接写(obj,1,2,3),如果这样写,就直接拆散成1,2,3,而add方法的参数是要传入一个int数组
  18.         }
  19. }
复制代码

作者: 黑马张旭明    时间: 2012-9-20 08:33
赵森羊 发表于 2012-9-20 07:50
给你写个列子:

有一点不明白,System.out.println(me.invoke(obj, new int[]{1,2,3}));这句
obj是指向了自己的子类对象,里面怎么会有子类的add方法
作者: zhaosenyang    时间: 2012-9-20 09:16
标题: RE: 谁想要技术分的,赶紧都来啊。过了这个村,可没这个店!
黑马张旭明 发表于 2012-9-20 08:33
有一点不明白,System.out.println(me.invoke(obj, new int[]{1,2,3}));这句
obj是指向了自己的子类对象 ...

obj是你由reflexpoint字节码文件创建的对象,obj指向这个对象,而调用的自然是这个对象的方法了
作者: 牛杨    时间: 2012-9-20 11:09
寇龙飞 发表于 2012-9-20 04:26
11楼正解哦。按照知识逻辑、跟着感觉走,就是用int[].class,不知道你怎么用的?贴你的代码。

这是我的代 ...

既然可以把int... 当做int[]  也就是说 把可变参数当作了一个数组来使用。
那么我 觉得这句 SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, arr);应该写成:
SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, (Object )arr); 比较合适,这个我也刚刚验证过,是正确的。
不过写成 SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, arr);也没问题。
我等会给你申请申请技术分去。

作者: 牛杨    时间: 2012-9-20 11:13
本帖最后由 牛杨 于 2012-9-20 11:21 编辑
赵森羊 发表于 2012-9-20 07:50
给你写个列子:


既然可以把int... 的Class实例认为是int[]  .class也就是说 把可变参数当作了一个数组来使用。
那么我 觉得这句 SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, arr);应该写成:
SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, (Object) arr); 比较合适,这个我也刚刚验证过,是正确的。
不过写成 SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, arr);也没问题。

谢谢兄弟帮忙解答啊!这个问题我已经明白了

作者: 寇龙飞    时间: 2012-9-20 20:52
牛杨 发表于 2012-9-20 11:09
既然可以把int... 当做int[]  也就是说 把可变参数当作了一个数组来使用。
那么我 觉得这句 SomeArgs.cla ...

SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, (Object )arr); 比较合适



为什么呢?
作者: 黄敏    时间: 2012-9-20 22:14
我认为这个问题老师在视频里已经讲解了 ,没记错的话  张老师应该讲了如何反射出主函数   可变参数跟主函数中的的 String一样的吧  只是形式不一样的,老师说过,在JDK1.5出现的可变参数 ,按说主函数 public static void main(String args[]){}  也应该写成 pubilc static void main(String...args){} 但是主函数的写法没有改变 就像老师说的,可能是历史遗留的问题  就是用习惯了   但是我相信也可以这样写pubilc static void main(String...args){};LZ可以试试

作者: 牛杨    时间: 2012-9-20 22:20
寇龙飞 发表于 2012-9-20 20:52
SomeArgs.class.getMethod("println", int[].class).invoke(someArgs, (Object )arr); 比较合适

因为 既然已经把这个 可变参数 看成了一个 数组 。 如果你通过invoke方法调用这个(把可变参数看做数组的)方法 传递实参的时候 就需要把把一个实参数组作为一个整体传递过去 。因此前面就需要加上一个Object了。
不过 不加那个Object也没啥问题。只是理解的时候,有些前后不一。
作者: 牛杨    时间: 2012-9-20 22:34
黄敏 发表于 2012-9-20 22:14
我认为这个问题老师在视频里已经讲解了 ,没记错的话  张老师应该讲了如何反射出主函数   可变参数跟主函数 ...

哇塞,我刚才试了试 主函数的 字符串数组 真的可以改成可变参数的形式啊。
我看到这个问题的时候是看到了 张老师说:只要是在源程序中出现的类型,都有各自的Class实例对象。 我当时想可变参数的Class实例对象是啥?这个问题想了好久没想明白 。后来学到了invoke方法就想到要提出这个问题。我提这个问题的时候,我在论坛上搜了搜 。发现13期也有一个兄弟提了这个问题。但是没有人能明明白白地回答。所以我就又提了一遍 。
作者: 王小闲7    时间: 2012-9-20 23:40
有些许的恐怖,鄙人表示还没看到这里……只能飘过
作者: 牛杨    时间: 2012-9-21 13:50
王小闲7 发表于 2012-9-20 23:40
有些许的恐怖,鄙人表示还没看到这里……只能飘过

没关系,总有一天会看到这里的。继续努力啊
作者: 尤圣回    时间: 2012-9-21 16:14
大哥换个头像吧 看着很别扭
作者: 牛杨    时间: 2012-9-21 20:11
尤圣回 发表于 2012-9-21 16:14
大哥换个头像吧 看着很别扭

那兄弟给我推荐个吧




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