黑马程序员技术交流社区

标题: 关于反射Field的问题 [打印本页]

作者: 王建雨    时间: 2012-2-7 20:54
标题: 关于反射Field的问题
本帖最后由 王建雨 于 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的值没有改变呢?
作者: 王建雨    时间: 2012-2-7 21:11
输出结果是:
aall
abc
不明白这是为什么....
作者: 最初的理想    时间: 2012-2-7 21:25
本帖最后由 最初的理想 于 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);
                        }
                }
        }
}

以上能达到目的
作者: 梅雄新    时间: 2012-2-8 00:36
楼主静态程序中的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);使其可见  其他类型可以不需要楼主可测试下
作者: 李泽霖    时间: 2012-2-8 09:53
通过查找api可知
Class.getDeclaredFields()
          返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
Field Class.getField(String name)
          返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。





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