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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 还不到时候 中级黑马   /  2013-11-24 11:42  /  1338 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我在家看张老师的教学视频,讲到反射时做了一个练习,我就照着视频上敲了一遍,但结果却不一样?求高手讲解,谢谢
  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.        
复制代码

评分

参与人数 1技术分 +1 黑马币 +5 收起 理由
枫儿 + 1 + 5 神马都是浮云

查看全部评分

5 个回复

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

评分

参与人数 1技术分 +1 黑马币 +5 收起 理由
枫儿 + 1 + 5 赞一个!

查看全部评分

回复 使用道具 举报
你的person类里字段的权限是默认权限,反射比public小的权限要用getDeclaredFields(),把第13行改成Field [] fields = obj.getClass().getDeclaredFields();或把字段权限改成public就可以了。如果是私有,要用暴力反射field.setAccessible(true)。

评分

参与人数 1技术分 +1 黑马币 +4 收起 理由
枫儿 + 1 + 4 赞一个!

查看全部评分

回复 使用道具 举报

RE: 关于反射的一个练习,不解?

刚看了API,确实是这样的。
顺便问下高手:getClass() 方法得到的Class是不是那个字节码对象所在类的内部类?

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

1.PNG

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

3.PNG
回复 使用道具 举报
获取字段的费方式修改一下:
Field [] fields = obj.getClass().getDeclaredFields()

评分

参与人数 1黑马币 +5 收起 理由
枫儿 + 5

查看全部评分

回复 使用道具 举报
还不到时候 发表于 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  吗?为什么?分别指向了什么对象?真的困惑?希望高手解答?有详细注释,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马