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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王建雨 黑马帝   /  2012-2-7 20:54  /  2385 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王建雨 于 2012-2-8 14:27 编辑

关于反射Field的问题,代码如下:
import java.lang.reflect.Field;
public class ReflectTest {
        public static void main(String[] args) throws Exception{
                ReflectPoint pt1 =new ReflectPoint();       
                System.out.println(pt1);
                toChange(pt1);
                System.out.println(pt1);
        }
        public static void toChange(Object obj) throws Exception {               
                Field [] fields = obj.getClass().getFields();
                for(Field field : fields){
                        if(field.getType() == String.class){
                                String oldField = (String)field.get(obj);
                                String newField = oldField.replace('b', 'a');
                                field.set(obj, newField);
                        }
                }
        }
}

public class ReflectPoint {
        public String st1 = "ball";
        String st2 = "abc";
        public String toString(){
                return st1+"\n"+st2 ;
        }
}
为什么str1的值改变了,而str2的值没有改变呢?

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1 sorry,失误。欢迎积极参加论坛交流.

查看全部评分

4 个回复

倒序浏览
输出结果是:
aall
abc
不明白这是为什么....
回复 使用道具 举报
本帖最后由 最初的理想 于 2012-2-7 21:27 编辑

楼主有个成员的访问权限是friendly所以要用暴力反射
代码如下
import java.lang.reflect.Field;

public class ReflectTest {
        public static void main(String[] args) throws Exception{
                ReflectPoint pt1 =new ReflectPoint();        
                System.out.println(pt1);
                toChange(pt1);
                System.out.println(pt1);
        }
        public static void toChange(Object obj) throws Exception {               
                Field [] fields = obj.getClass().getDeclaredFields();//修改之处
                for(Field field : fields){
                          
                                 if(field.getType() == String.class){
                                                 field.setAccessible(true);        //注意此处
                                String oldField = (String)field.get(obj);
                                String newField = oldField.replace('b', 'a');
                              
                                field.set(obj, newField);
                        }
                }
        }
}

以上能达到目的

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
楼主静态程序中的toChange方法中getFields()获取的是字节码中反映此 Class 对象所表示的类或接口的所有可访问公共字段,即被public 修饰的属性
在ReflectPoint 中 的属性只有st1是public类型,st2是默认属性 所以用getFields()只能获取st1
要想获取到非公共的字段可以用getDeclaredFields()获取此Class所声明的所有字段
只需修改toChange()方法即可,如下测试通过
public static void toChange(Object obj) throws Exception {               
                              Field [] fields = obj.getClass().getDeclaredFields();
                for(Field field : fields){
                        if(field.getType() == String.class){
                                String oldField = (String)field.get(obj);
                                String newField = oldField.replace('b', 'a');
                                field.set(obj, newField);
                        }
楼上所说的暴力是对私有private变量来说的,要field.setAccessible(true);使其可见  其他类型可以不需要楼主可测试下

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
通过查找api可知
Class.getDeclaredFields()
          返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
Field Class.getField(String name)
          返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马