使用类的反射机制来访问类的私有成员变量

来源:互联网 发布:淘宝下架再上架 编辑:程序博客网 时间:2024/05/22 14:09

首先我们来看个实例吧,一般根据Java的语法,类的私有成员变量只能被内部的方法所访问;但是通过类的反射机制,却可以访问这个类的所有变量(包括私有成员变量),

我们这个实例吧。

import java.lang.reflect.Field;public class PrivateTest1 {/** * @param args */public static void main(String[] args)throws Exception {PrivateTestClass1 obj =new PrivateTestClass1("leonardo"); //获取对象//获取Class 对象Class clazz =obj.getClass();Field f =clazz.getDeclaredField("field"); //获取类的field//设置 私有变量可以访问的权限f.setAccessible(true);//打印field的值System.out.println(f.get(obj));}}class PrivateTestClass1{private String field;public PrivateTestClass1(String field){this.field =field;}}
这里的关键是将私有变量的访问权限改为true  否则类的反射也是无法访问的。

接下来我这边要做一个拓展;是这些天面试的时候,碰到一个面试题:

能否将ReadOnlyClass 类的一个对象,把它的name属性的值由hello改为world?如果能,请写出实现代码。如果不能请说明理由。
Public final class ReadOnlyClass (
           private String name = “hello”;
           public String getName() {
                       return name;
            }

}

 刚开始的时候 ,我竟然不加思考的回答不可以(由于该私有变量没有set方法),可是回来仔细一想不对劲了;因为类的反射是可以处理的。下面我们就用类的反射来解决这个问题。

import java.lang.reflect.Field;/** * 类反射 访问私有变量、修改私有变量 * @author leo * */public class PrivateTest {/** * @param args  */public static void main(String[] args) throws Exception {PrivateTestClass obj =new PrivateTestClass();Class clazz =obj.getClass(); //获取obj对象的 class Field f =clazz.getDeclaredField("name"); //获取类的field//关键步骤f.setAccessible(true); //设置私有变量的可访问性为trueSystem.err.println(f.get(obj));// ,可以同累的反射进行修改 木有set方法的 私有变量f.set(obj, "world");//打印出对象System.out.println(f.get(obj));}}final class PrivateTestClass{private String name ="hello";public String getName() {return name;}}

编写完成之后,我们进行编译运行一下,发现打印出来的两个 值:

hello
world

看见没有,类的反射是可以处理该种情况,当然这种情况在我们框架中是很常见的。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

实例2:利用反射将一个bean的对象的值  封装到map中 

在写service 层接口时,为了让每个接口方法的可用性更广,我在项目中定义参数都是用一个Map<String,Object> 来定义;可是controller 传递过来的参数都是一个VO 的bean 对象,所以我为了代码可维护性更高,减少冗余代码,用反射写了个工具类;

beanVO :

package com.zeng.map;public class Student {private String name;private String age;private String sex;private String grade;private String className;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getGrade() {return grade;}public void setGrade(String grade) {this.grade = grade;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}}

工具类以及测试方法:

package com.zeng.map;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;/** * 利用反射将一个bean 的对象的值封装到Map中 * @author leo-zeng * */public class BeanUntils {public static <T> Map<String,Object> convertBeanToMap(T t) throws Exception{Map<String,Object> condition = new HashMap<String, Object>();//获取类的实例Field[] fields = t.getClass().getDeclaredFields();for (Field field : fields) {//设置字段是可访问的field.setAccessible(true);Object value  =field.get(t);if(value != null){if(value instanceof String){String _v = (String)value;if(_v != null && _v.trim().length()>0){condition.put(field.getName(), _v.trim());}}else{condition.put(field.getName(), value);}}}return condition;}public static void main(String[] args) {Student student = new Student();student.setName("leo");student.setAge("22");student.setGrade("3");try {Map<String,Object> condition =BeanUntils.convertBeanToMap(student);for (Map.Entry<String, Object> entry : condition.entrySet()) {System.out.println(entry.getKey()+":"+entry.getValue());}} catch (Exception e) {e.printStackTrace();}}}

得到的测试结果是

age:22
name:leo
grade:3







0 0
原创粉丝点击