buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

java reflection exception--can not access a member of class XXX with modifiers "private"

look at the sample program below. It works when I run it.

Field[] fields = reflectAllFields(parameter);
for (Field field : fields) {
    if ("createTime".equals(field.getName())) {
        field.setAccessible(true);
        Object localCreateDate = field.get(parameter);
        if (localCreateDate == null || "".equals(localCreateDate)) {
            if (field.getType() == Date.class) {
                field.set(parameter, DateUtils.getPlusDaysDate( new Date(),10));
            } else if (field.getType() == LocalDateTime.class) {
                field.set(parameter, LocalDateTime.now());
            }
        }
    }
}

 

the involved utility method  reflectAllFields  is defined in the same class.

// import java.lang.reflect.Field;

private static Field[] reflectAllFields(Object object) {
    Class<?> clazz = object.getClass();
    List<Field> fieldList = new ArrayList<>();
    while (clazz != null) {
        fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
        clazz = clazz.getSuperclass();
    }
    Field[] fields = new Field[fieldList.size()];
    fieldList.toArray(fields);
    return fields;
}
View Code

 

Then, I make a little adjustment, see below. Run it again, and the program throws an exception → can not access a member of class com.emaxcard.account.entity.Account with modifiers "private"

Field[] fields = reflectAllFields(parameter);
for (Field field : fields) {
    if ("createTime".equals(field.getName())) {
        Object localCreateDate = field.get(parameter);
        if (localCreateDate == null || "".equals(localCreateDate)) {
            field.setAccessible(true);
            if (field.getType() == Date.class) {
                field.set(parameter, DateUtils.getPlusDaysDate( new Date(),10));
            } else if (field.getType() == LocalDateTime.class) {
                field.set(parameter, LocalDateTime.now());
            }
        }
    }
}

 

Here are the stacktraces :

java.lang.IllegalAccessException: Class com.emaxcard.account.config.MybatisInterceptor can not access a member of class com.emaxcard.account.entity.Account with modifiers "private"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
    at java.lang.reflect.Field.get(Field.java:390)
    at com.emaxcard.account.config.MybatisInterceptor.intercept(MybatisInterceptor.java:89)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
    at com.sun.proxy.$Proxy157.update(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
    ... 50 more

 

 

I note that The mentioned field com.emaxcard.account.entity.Account#createTime is private. When I change it to public, the above IllegalAccessException disappears. Of course, we should define fields as private, that's the POJO specification.

 

In a word, If you try to visit the value of an object's private field using reflection, such as Field#get or Field#set, you should call Field#setAccessible(true) ahead.

 

 

 setAccessible(true)  is used to open up access to non-public members or methods, such as private member variables or methods.

The way to access and modify public and private member variables is different, and you need to choose the appropriate method based on the access level of the member variable.

- If you use reflection to retrieve a public member variable of a class (using the getField method), you don't need to call setAccessible(true) to access or modify the value of the variable. This is because public member variables can be accessed and modified from outside the class.

- If you use reflection to retrieve a private member variable of a class (using the getDeclaredField method), you need to call setAccessible(true) to open up access, otherwise you'll get an IllegalAccessException. This is because private member variables cannot be accessed or modified from outside the class.

 

posted on 2023-03-28 11:02  buguge  阅读(439)  评论(0编辑  收藏  举报