在Users的实体类有四个属性并生成了公开的set和get方法
private String id;
private String username;
private String password;
private int age;
在下面的类中getProperty方法获得指定对象实例属性的值
但出现异常
Exception in thread "main" java.lang.IllegalAccessException: Class example1.Reflection can not access a member of class example1.Users with modifiers "private"
是执行到obj = f.get(owner);出现的异常
觉得疑惑是通过getDeclaredField()获得的属性为什么不能是私有的呢。。
package example1;import java.lang.reflect.Field;
import java.lang.reflect.Method;import org.apache.commons.beanutils.BeanUtils;public class Reflection {

public static Object getProperty(Object owner ,String propertyName) throws Exception{
Object obj = null;
Class clazz = owner.getClass();
Field f = clazz.getDeclaredField(propertyName);
obj = f.get(owner);
return obj;
}

public static void main(String[] args) throws Exception {
Users u = (Users)Reflection.getInstance("example1.Users");
u.setId("aaaaaaaaaaaa");
u.setAge(12);
u.setPassword("12321321");
u.setUsername("userse");
System.out.println(Reflection.getProperty(u,"age")); }
}

解决方案 »

  1.   

    加f.setAccessible(true);
    取消 Java 语言访问检查
      

  2.   

    很明显的问题..私有构造方法能够直接在外面获得值吗?你可以试着将private int age改成public int age如果你不想声明成私有的,那就调用这个字段的getter方法...
      

  3.   


    因为age是private的,所以要加上f.setAccessible(true); 
      

  4.   

    private 你要有getter/setter方法
    当然代理不会自动帮你获取getter/setter 你要自己些个代理方法获得getter/setter 如下:
    Field[] field = clazz.getDeclaredFields();
    for (Field field2 : field) {
                            //获取属性名
    String fieldName= field2.getName();
                            //获取属性名的第一个字母然后转换成大写  id  ----》  i
    String MethodName = fieldName.substring(0,1).toUpperCase();
                            //get + I + d;
    String getMethodName = "get" + MethodName + fieldName.substring(1);
    //set + I + d;
    String setMethodName = "set" + MethodName + .fieldName.substring(1);
    //调用get + I + d的方法
    Method getMethod = clazz.getDeclaredMethod(getMethodName, new Class[]{});
    //调用set + I + d的方法  field2.getType就是 setId(类型)
    Method setMethod = clazz.getDeclaredMethod(setMethodName, new Class[]{field2.getType});
    //调用set + I + d的方法 并且付值
    setMethod.invoke(Invoke, new Object[]{"TClazzMethod"});                        ……一下方法同样 }
      

  5.   

    其实我感觉你还是用构造付值方便很多 不用写getter/setter方法
    Object invokeTester = clazz.getConstructor(new Class[]{String.class,String.class,String.class,Integer.TYPE(int.class)}).newInstance(new Object[]{"1","Make","make123",20}); Method method = clazz.getMethod(方法,new Class[]{});

    method.invoke(invokeTester, new Object[]{});