黑马程序员技术交流社区

标题: 关于反射的一个练习,不解? [打印本页]

作者: 还不到时候    时间: 2013-11-24 11:42
标题: 关于反射的一个练习,不解?
我在家看张老师的教学视频,讲到反射时做了一个练习,我就照着视频上敲了一遍,但结果却不一样?求高手讲解,谢谢
  1. //需求:将任意一个Person类的对象中所有String类型的属性中'a'换成'b'
  2. public class ReflectDemo {

  3.        
  4.         public static void main(String[] args) throws Exception {
  5.                 Person p = new Person(20);
  6.                 changeString(p);
  7.                 System.out.println(p);
  8.         }

  9.         public static void changeString(Object obj) throws Exception{
  10.                 //通过反射获取字段对象数组
  11.                 Field [] fields = obj.getClass().getFields();
  12.                 //遍历数组
  13.                 for(Field field:fields){
  14.                         //判断字段对象的类型是否为String类型
  15.                         if(field.getType()== String.class){
  16.                                 //获取传入对象的String类型属性
  17.                                 String oldStr = (String)field.get(obj);
  18.                                 //创建一个新的属性,替代之前String类型的属性
  19.                                 String newStr = oldStr.replace('a','b');
  20.                                 //将新创建的String类型属性设为这个对象的属性。
  21.                                 field.set(obj, newStr);
  22.                         }
  23.                 }
  24.                
  25.         }
  26.        
  27.        

  28. }
  29. class Person{
  30.         String name = "zhangsan" ;
  31.         String str = "itcast";
  32.         int age ;
  33.        
  34.         Person(int age) {
  35.                 super();
  36.                 this.age = age;
  37.         }
  38.         public String toString(){
  39.                 return "姓名:"+name+":"+str;
  40.         }
  41.        
复制代码

作者: 未知数|X|    时间: 2013-11-24 12:23
Fileld[] fields=obj.getFields(),它返回的是所有允许访问的public类型的属性的数组,
你的Person对象里面的所有属性都是采用JAVA默认类型也就是friendly,与这个getFields();的要求是不符合的,你打印出fields.length结果肯定是0;你把Person里面的所有属性都加上public如下:、
public String name = "zhangsan" ;
  public  String str = "itcast";
这样就会得出你想要的结果,把a替换成了b

作者: 繁华终成泣    时间: 2013-11-24 12:53
你的person类里字段的权限是默认权限,反射比public小的权限要用getDeclaredFields(),把第13行改成Field [] fields = obj.getClass().getDeclaredFields();或把字段权限改成public就可以了。如果是私有,要用暴力反射field.setAccessible(true)。
作者: 还不到时候    时间: 2013-11-24 14:00
标题: RE: 关于反射的一个练习,不解?
刚看了API,确实是这样的。
顺便问下高手:getClass() 方法得到的Class是不是那个字节码对象所在类的内部类?

1.PNG (31.87 KB, 下载次数: 14)

1.PNG

3.PNG (36.91 KB, 下载次数: 10)

3.PNG

作者: 。子伤。    时间: 2013-11-24 14:10
获取字段的费方式修改一下:
Field [] fields = obj.getClass().getDeclaredFields()
作者: 还不到时候    时间: 2013-11-24 14:46
还不到时候 发表于 2013-11-24 14:00
刚看了API,确实是这样的。
顺便问下高手:getClass() 方法得到的Class是不是那个字节码对象所在类的内部类 ...

后面问的那个问题中的getClass()是Class类中的getClass()方法
例:定义一个Person类,通过反射过去字节码文件对象
Person p = new Person();
Class clazz = p.getClass();
接着调用clazz的getClass()方法
Class clazz1 = p.getClass().getClass();
clazz ==clazz1  吗?为什么?分别指向了什么对象?真的困惑?希望高手解答?有详细注释,谢谢




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