Java reflection - access protected field

2019-01-21 19:17发布

How can I access an inherited protected field from an object by reflection?

10条回答
淡お忘
2楼-- · 2019-01-21 19:43

If you are just getting the protected field

Field protectedfield = Myclazz.class.getSuperclass().getDeclaredField("num");

If you are using Eclipse Ctrl + Space will bring up a list of methods when you type a "." after the object

查看更多
再贱就再见
3楼-- · 2019-01-21 19:46

Do you perhaps mean from a different object an untrusted context with a SecurityManager set? That would break the type system, so you can't. From a trusted context, you can call setAccessible to defeat the type system. Ideally, don't use reflection.

查看更多
Deceive 欺骗
4楼-- · 2019-01-21 19:47

Use FieldUtils.writeField(object, "fieldname", value, true) or readField(object, "fieldname", true) from Apache Commons lang3.

查看更多
三岁会撩人
5楼-- · 2019-01-21 19:52

I didn't want to drag in more libraries so I made a pure one that worked for me. It is an extension of one of the methods from jweyrich:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

public abstract class POJOFiller {

    static final Random random = new Random();

    public static void fillObject(Object ob) {
        Class<? extends Object> clazz = ob.getClass();

        do {
            Field[] fields = clazz.getDeclaredFields();
            fillForFields(ob, fields);

            if (clazz.getSuperclass() == null) {
                return;
            }
            clazz = clazz.getSuperclass();

        } while (true);

    }

    private static void fillForFields(Object ob, Field[] fields) {
        for (Field field : fields) {
            field.setAccessible(true);

            if(Modifier.isFinal(field.getModifiers())) {
                continue;
            }

            try {
                field.set(ob, generateRandomValue(field.getType()));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    static Object generateRandomValue(Class<?> fieldType) {
        if (fieldType.equals(String.class)) {
            return UUID.randomUUID().toString();
        } else if (Date.class.isAssignableFrom(fieldType)) {
            return new Date(System.currentTimeMillis());
        } else if (Number.class.isAssignableFrom(fieldType)) {
            return random.nextInt(Byte.MAX_VALUE) + 1;
        } else if (fieldType.equals(Integer.TYPE)) {
            return random.nextInt();
        } else if (fieldType.equals(Long.TYPE)) {
            return random.nextInt();
        } else if (Enum.class.isAssignableFrom(fieldType)) {
            Object[] enumValues = fieldType.getEnumConstants();
            return enumValues[random.nextInt(enumValues.length)];
        } else if(fieldType.equals(Integer[].class)) {
            return new Integer[] {random.nextInt(), random.nextInt()};
        }
        else {
            throw new IllegalArgumentException("Cannot generate for " + fieldType);
        }
    }

}
查看更多
做个烂人
6楼-- · 2019-01-21 19:53

You could do something like...

Class clazz = Class.forName("SuperclassObject");

Field fields[] = clazz.getDeclaredFields();

for (Field field : fields) {
    if (field.getName().equals("fieldImLookingFor")) {
        field.set...() // ... should be the type, eg. setDouble(12.34);
    }
}

You might also need to change the accessibility, as noted in Maurice's answer.

查看更多
姐就是有狂的资本
7楼-- · 2019-01-21 19:55
field = myclass.getDeclaredField("myname");
field.setAccessible(true);
field.set(myinstance, newvalue);
查看更多
登录 后发表回答