黑马程序员技术交流社区

标题: 反射中获取构造函数参数的问题 [打印本页]

作者: 彭坤    时间: 2012-2-23 17:23
标题: 反射中获取构造函数参数的问题
基础加强视频里,在看到通过反射获得构造方法生成实例时有一个地方一直转不过弯,遂上论坛求教
代码如下:

  1. Constructor constructor = String .class.getConstructor(StringBuffer.class);//getConstructor(StringBuffer.class)
  2. //上面一行代码中,小括号里面的StringBuffer.class是怎么确定的?不是说运行时才能确定String类吗?
  3. String str = constructor.newInstance(new StringBuffer("abc"));
复制代码
那么、再看下面的代码
  1. class Student{
  2.         @Override
  3.         public String toString() {
  4.                 return "name:"+ name + "age="+ age;
  5.         }
  6.         private String name;
  7.         private int age;
  8.         public String getName() {
  9.                 return name;
  10.         }
  11.         public void setName(String name) {
  12.                 this.name = name;
  13.         }
  14.         public int getAge() {
  15.                 return age;
  16.         }
  17.         public void setAge(int age) {
  18.                 this.age = age;
  19.         }
  20.         public Student(){}
  21.         public Student(String name, int age) {
  22.                 this.name = name;
  23.                 this.age = age;
  24.         }
  25. }
复制代码
上面的的Student类有两个构造方法,一个是无参的,一个是接收name&age两个参数的,那如何通过反射确定Student类中两个构造方法参数类型和个数呢?
作者: 丁晓宇    时间: 2012-2-23 17:31
建议你休息一下不要想这个问题  然后再看一下关于反射的视频,你现在进入误区了
作者: 彭坤    时间: 2012-2-23 17:35
丁晓宇 发表于 2012-2-23 17:31
建议你休息一下不要想这个问题  然后再看一下关于反射的视频,你现在进入误区了 ...

拉我一把吧,看了N遍,就没讲这个问题
作者: 丁晓宇    时间: 2012-2-23 17:49
那你打印一下 类.class 看是什么
作者: 沙漠里的小鱼    时间: 2012-2-23 20:51
本帖最后由 沙漠里的小鱼 于 2012-2-23 20:52 编辑

其实反射中获取构造方法很简单的啊  public Student(String name, int age) {
   this.name = name;
  this.age = age;
这反射的 的时候要知道是是哪个 这个是String.class ,Int.class  
如果反射是一般的方法反射
就是mthod的时候 还要有具体哪个方法的名字 然后在加String.class ,Int.class 这些参数来确定具体哪个方法

我也有个问题请教你啊  String s = new String(new StringBuffer("a"))和String s = new String("a")区别 我们创建一个实例对象 一般都是String s = new String("a")     为什么在讲反射举例创建对象是时候是String s = new String(new StringBuffer("a"))    里面多了个new StringBuffer   

作者: 黄秋    时间: 2012-2-23 20:59
彭坤 发表于 2012-2-23 17:35
拉我一把吧,看了N遍,就没讲这个问题

1. 不是“看了N遍”就行的,要沉下心来,不浮躁,认真看。
2. 老实说,我不想答这问题的。论坛逛得多,视频很多没看,以至技术分高,但日志还没写完。反射还没看到呢,但你对这似乎很困苦(昨天也有人问了类似问题),跳到反射的视频看了。
3. 老师说得挺好的,他只是举了StringBuffer 作为参数的构造方法的例子,不一定要是StringBuffer.class,完全可用 String.class:
  1.         Constructor constructor = String .class.getConstructor(String.class);
  2.         String str = (String)constructor.newInstance(new String("abc"));
  3.         System.out.println(str);
复制代码
4. 再下面代码, constructor 、constructor1 只是参数不同,仅此而已:
  1.                 Constructor constructor = String .class.getConstructor(String.class);
  2.                 String str = (String)constructor.newInstance(new String("abc"));
  3.                 System.out.println(str);
  4.                 System.out.println(constructor.toGenericString()); //constructor的参数是String
  5.                
  6.                 Constructor constructor1 = String .class.getConstructor(StringBuffer.class);
  7.                 String str1 = (String)constructor1.newInstance(new StringBuffer("abc"));               
  8.                 System.out.println(constructor1.toGenericString()); //constructor1的参数是StringStringBuffer
复制代码
5. 接下来,加深理解:
  1. Object obj1 = constructor1.newInstance(new StringBuffer("abc"));
  2. Object obj2 = constructor.newInstance("abc");
  3. // Object obj2 = constructor1.newInstance("abc"); //编译行,运行报参数类型不匹配
复制代码
不解释了。其实,初学反射,看 Object obj2 = constructor.newInstance("abc"); 易明白。

PS: 多思考多动手,更要勤试验,试验比动手更高一层次。
作者: 彭坤    时间: 2012-2-23 21:31
黄秋 发表于 2012-2-23 20:59
1. 不是“看了N遍”就行的,要沉下心来,不浮躁,认真看。
2. 老实说,我不想答这问题的。论坛逛得多,视 ...

谢谢你的回答,不过貌似你没看清楚我的困惑到底是什么。。。。。
String类是我们经常用的类,大家熟悉得狠,即使不查API文档我们都可以知道它有哪些构造方法,都传哪些参数。
张老师讲课时所使用的是String类的一个以StringBuffer对象为参数的构造方法。假如我们对String类一无所知,只知道java.lang.String,在不查API的情况下,如何在运行时获取String类众多带不同参数的构造方法?
(反射定义:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性、方法、构造方法、修饰符、包等信息),同理我要问的是,如何通过反射获取我所定义的Student类中的两个不同构造函数的参数个数以及类型。
我不知道我是不是真的陷入了一个怪圈,希望能再次得到你的回答
PS:google了好久,发现大家都像知道需要用到的类是什么样的构造似的,拿着就直接用,但事实是我们事先是不知道的。求真相,各种真相。。。。。。。
作者: tanlei200620    时间: 2012-2-23 22:19
     小括号里面的StringBuffer.class是怎么确定的(类加载器加载  字节码文件  确定的,),平常的运行大多是new的时候才加载字节码文件,你直接用类名.class相当于直接命令类加载器加载你需要的字节码文件 。这样你能理解了么?
作者: 黄秋    时间: 2012-2-23 22:52
彭坤 发表于 2012-2-23 21:31
谢谢你的回答,不过貌似你没看清楚我的困惑到底是什么。。。。。
String类是我们经常用的类,大家熟悉得 ...

前面已有人(沙漠里的小鱼 )答了:

其实反射中获取构造方法很简单的啊  public Student(String name, int age) {
   this.name = name;
  this.age = age;
这反射的 的时候要知道是是哪个 这个是String.class ,Int.class  
如果反射是一般的方法反射
就是mthod的时候 还要有具体哪个方法的名字 然后在加String.class ,Int.class 这些参数来确定具体哪个方法

类 Field 可以 "获取我所定义的Student类中的两个不同构造函数的参数个数以及类型",如果你还是不清楚,我抽时间写写。看来我前面是回答了”沙漠里的小鱼“的那个帖子。
作者: 黄秋    时间: 2012-2-23 23:37
类 Field 说错了,其实与其差不多:
  1. Constructor[] cons = Student.class.getDeclaredConstructors();
  2. for(Constructor c:cons)
  3.         System.out.println(c);
复制代码

作者: 【专】【属】    时间: 2012-2-24 10:40
我在网上看了一下java的API在Construtor类中看到这样一个方法getParameterTypes
就应该是得到一个构造方法中的参数列表中参数的类型的字节码的一个数组,个人想小伙可以看一下。




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