1. 程式人生 > >無視修飾符,不經過getter函式直接獲取物件的某個欄位的屬性值

無視修飾符,不經過getter函式直接獲取物件的某個欄位的屬性值

直接上程式碼:

public class ReflectionUtils {
/**
 * 直接讀取物件屬性值, 無視private/protected修飾符, 不經過getter函式.
 */
public static Object getFieldValue(final Object obj, final String fieldName) {
    Field field = getAccessibleField(obj, fieldName);

    if (field == null) {
        throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
    }

    Object result = null;
    try {
        result = field.get(obj);
    } catch (IllegalAccessException e) {
    }
    return result;
}
/**
 * 迴圈向上轉型, 獲取物件的DeclaredField, 並強制設定為可訪問.
 * 
 * 如向上轉型到Object仍無法找到, 返回null.
 */
public static Field getAccessibleField(final Object obj, final String fieldName) {
    Validate.notNull(obj, "object can't be null");
    Validate.notBlank(fieldName, "fieldName can't be blank");
    for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
        try {
            Field field = superClass.getDeclaredField(fieldName);
            makeAccessible(field);
            return field;
        } catch (NoSuchFieldException e) {// NOSONAR
            // Field不在當前類定義,繼續向上轉型
            continue;// new add
        }
    }
    return null;
}
/**
 * 改變private/protected的成員變數為public,儘量不呼叫實際改動的語句,避免JDK的SecurityManager抱怨。
 */
public static void makeAccessible(Field field) {
    if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
        .isFinal(field.getModifiers())) && !field.isAccessible()) {
        field.setAccessible(true);
    }
}

}