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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 薛飞飞 黑马帝   /  2012-4-16 18:59  /  2125 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

为什么这个方法不能给一个Person类的年龄属性age 赋值?
  1. import java.lang.reflect.Method;

  2. public class FiledsUntil {
  3. private FiledsUntil(){}
  4. // 为一个对象的属性赋值 name setName age setAge
  5. public static void setProperty(Object obj, String fieldName, Object value) throws Exception {
  6. // 1. 通过obj对象获得类型 Class对象
  7. Class clazz = obj.getClass();
  8. // 2. 解析字段,但是字段通常私有,应该去反射 setXxx 方法
  9. // 拼写方法名称
  10. String setMethodName = "set" + String.valueOf(fieldName.charAt(0)).toUpperCase() + fieldName.substring(1);
  11. System.out.println(setMethodName);
  12. // 获得参数类型
  13. Class paramType = value.getClass();
  14. // 反射 Method
  15. Method setMethod = clazz.getMethod(setMethodName, paramType);
  16. // 3. 调用 setXxx 方法赋值
  17. setMethod.invoke(obj, value);
  18. }
  19. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

8 个回复

倒序浏览
value是Object
Class paramType = value.getClass(); 得到的是Object.class
所以反射方法的时候得到的是名字是setAge参数为Object的函数。。。所以没有找到

反射JavaBean的set方法可以这样:
Person person = new Person();
propertyName = "age";
PropertyDecriptor pd = new PropertyDecriptor(propertyName,person.getClass());
Method methodSetAge = pd.getWriteMethod();

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
value类型为Object,Class paramType = value.getClass();此时paramType为Object.class
通过反射使用的方法参数应该是Object类型的,而设置年龄传的的是Integer类型的参数,
所以……
回复 使用道具 举报
刘元明 发表于 2012-4-16 21:55
value类型为Object,Class paramType = value.getClass();此时paramType为Object.class
通过反射使用的方法 ...

Integer是Obiect子类,我传的参数是int类型,会自动装箱成Integer类型,赋值时会自动拆箱为int类型的,所以这块应该没问题的...
回复 使用道具 举报
罗杰 发表于 2012-4-16 21:15
value是Object
Class paramType = value.getClass(); 得到的是Object.class
所以反射方法的时候得到的是名 ...

javaBean方法我知道,但这个程序按理可以给任意属性赋值的,所以要考虑的不是换方法,而是怎么修改这个程序区解决这个问题...
回复 使用道具 举报
薛飞飞 发表于 2012-4-16 22:10
Integer是Obiect子类,我传的参数是int类型,会自动装箱成Integer类型,赋值时会自动拆箱为int类型的,所 ...

函数不能知道运行的时候传了个什么类型的参数,编译的时候定义的value是Object类型的,所以就是Object了

不用那个方法的话。。。你可以手动传个参数类型列表作为setProperty的一个参数,直接传给paramType
调用时候这样:
Person person = new Person();
FiledsUntil.setProperty(person,"age",20,int.class);
回复 使用道具 举报
薛飞飞 发表于 2012-4-16 22:10
Integer是Obiect子类,我传的参数是int类型,会自动装箱成Integer类型,赋值时会自动拆箱为int类型的,所 ...

也许我说的有问题,设置年龄的参数应该是int.class,既不是Object.class也不是Integer.class,这里并不是用自动装箱理论解释的,这类问题参数之间不要考虑继承一类的关系
回复 使用道具 举报
薛飞飞 发表于 2012-4-16 22:15
javaBean方法我知道,但这个程序按理可以给任意属性赋值的,所以要考虑的不是换方法,而是怎么修改这个程 ...

下面几步即可:
Method setAge=Person.class.getMethod("setAge", int.class);
Person p=new Person();
setAge.invoke(p,23);
你可以再验证看看,仅供参考
回复 使用道具 举报
张超超 黑马帝 2012-4-18 16:29:29
9#
其实呢,你对反射的理解不是很深刻,这里有关于反射的介绍:

 JAVA反射机制定义:   JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。   Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。   有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。   一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。   尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。   Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。

希望对你有帮助。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马