黑马程序员技术交流社区

标题: 反射上的使用小问题 [打印本页]

作者: 张飞年    时间: 2012-9-22 11:31
标题: 反射上的使用小问题
本帖最后由 张飞年 于 2012-9-22 11:39 编辑

在使用getConstructor()获取到构造器对象,再用它的newInstance(Paramter)方法创建类对象后用取字段的方法getField()时候取出的字段内容为什么为空呢?这样说着可能听的糊涂,看代码吧:
这是Person相关的代码:
  1. public class Person {
  2.         private String name;
  3.         public String getName() {
  4.                 return name;
  5.         }
  6.         public void setName(String name) {
  7.                 this.name = name;
  8.         }
  9. public Person(){
  10.                 System.out.println("构造函数");
  11.         }
  12.         public Person(String name, int age){
  13.                 System.out.println("paramter构造函数" + name + "--" + age);
  14.         }
  15. //其他的省略
  16. }
复制代码
  1. public class TestReflect3{
  2.         public static void main(String[] args) throws Exception {
  3.                 String str = "com.test.day14.Person";
  4.                 Class clazz =Class.forName(str);
  5.                 Constructor c = clazz.getConstructor(String.class,int.class);//获取到有参的构造方法,注意后面的参数都是对应的类型的class类型
  6.                 Object o = c.newInstance("xiaoming",29);//用构造器的方法newInstance构造带参的文件类对象,这里的返回Person对象
  7.                 System.out.println(o);
  8.                 Field field = clazz.getDeclaredField("name");//取得私有的name字段
  9.                 field.setAccessible(true);//强行访问
  10.                 //field.set(o, "xiaoqiang");//<font color="blue">不明白 的是:这里如果不设置字段值,oo那里就是null,也就是说取不到有参构造器初始化的“xiaoming”</font>
  11.                 Object oo = field.get(o);//<font color="blue">如果上步set了o对应的field值,则可以正常取到“xiaoqiang”</font>
  12.                 System.out.println(oo);
  13.         }
  14. }
  15.       
复制代码

作者: 程金    时间: 2012-9-22 11:54
本帖最后由 程金 于 2012-9-22 11:55 编辑

public class TestReflect3{
        public static void main(String[] args) throws Exception {
                String str = "com.test.day14.Person";
                Class clazz =Class.forName(str);
                Constructor c = clazz.getConstructor(String.class,int.class);//获取到有参的构造方法,注意后面的参数都是对应的类型的class类型
                Object o = c.newInstance("xiaoming",29);//用构造器的方法newInstance构造带参的文件类对象,这里的返回Person对象
                System.out.println(o);
                Field field = clazz.getDeclaredField("name");//取得私有的name字段
                field.setAccessible(true);//强行访问
                //field.set(o, "xiaoqiang");//<font color="blue">不明白 的是:这里如果不设置字段值,oo那里就是null,也就是说取不到有参构造器初始化的“xiaoming”</font>
------------------------------------------
反射根本不需要实例对象就能得到
因为Field field=clazz.getDeclaredField("name"),得到的是表示Person的Class类对象的Field类的成员变量的对象
它是一个类,它的获取跟Person类的实例对象无关,,他不是从你new的person实例对象中获取的,他是从Person的Class类对象中获取
没有实例对象也能获取这个Field类类对象,由于你在Person类中没有显式初始化;
所以通过反射获得的Field也没有显式初始化,所以是默认值null.
   你在Person类中显式初始化就可以了. 改成:private String name="xiaoqing";


__________________________________________--
                Object oo = field.get(o);//<font color="blue">如果上步set了o对应的field值,则可以正常取到“xiaoqiang”</font>
                System.out.println(oo);
        }
}
作者: 张飞年    时间: 2012-9-22 12:04
程金 发表于 2012-9-22 11:54
public class TestReflect3{
        public static void main(String[] args) throws Exception {
        ...

嗯,,你说的赞同,我也看出问题来了,是我的Person里面的name没有初始化。应该public Person(String name, int age){

System.out.println("paramter构造函数" + name + "--" + age);
this.name = name ;//这里没有让其为成员变量赋值,
}
========================
ps:反射给讲起来还真费劲昻,我说的也费劲你回答的也费劲,不过我也看懂了,所以这反射还是得认真学好原理性的东西。
作者: 赵永康    时间: 2012-9-22 12:16
通过Reflect set method以后,就是给Field赋值了,没有set就用在Class中声明的了,因此是null.




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