Получить все поля (даже частные и унаследованные) из класса
Я делаю университетский проект.
Мне нужно получить все поля из класса. Даже частные и унаследованные. Я попытался получить все объявленные поля, а затем бросил суперкласс и повторил.
Фрагмент моего кода:
private void listAllFields(Object obj) {
List<Field> fieldList = new ArrayList<Field>();
while (obj != null) {
fieldList.addAll(Arrays.asList(obj.getClass().getDeclaredFields()));
obj = obj.getClass().getSuperclass().cast(obj);
}
// rest of code
Но это не сработает. tmpObj
после литья по-прежнему остается одним и тем же классом (не суперклассом).
Я буду признателен за любую помощь, как исправить проблему кастинга или как получить эти поля по-разному.
EDIT:
Проблема заключается не в получении доступа к полям, а в получении имен полей!
Я управляю этим способом:
private void listAllFields(Object obj) {
List<Field> fieldList = new ArrayList<Field>();
Class tmpClass = obj.getClass();
while (tmpClass != null) {
fieldList.addAll(Arrays.asList(tmpClass .getDeclaredFields()));
tmpClass = tmpClass .getSuperclass();
}
// rest of code
Ответы
Ответ 1
obj = obj.getClass().getSuperclass().cast(obj);
Эта строка не делает то, что вы ожидаете от нее. Кастинг объекта фактически не меняет его, он просто говорит компилятору рассматривать его как нечто другое.
например. вы можете применить List
к Collection
, но он все равно останется списком.
Однако, переполнение суперклассов для доступа к полям отлично работает без кастинга:
Class<?> current = yourClass;
while(current.getSuperclass()!=null){ // we don't want to process Object.class
// do something with current fields
current = current.getSuperclass();
}
Кстати, если у вас есть доступ к Spring Framework, есть удобный метод для прокрутки полей класса и всех суперклассов:
ReflectionUtils.doWithFields(baseClass, FieldCallback)
(также см. предыдущий мой ответ: Доступ к приватным унаследованным полям через отражение в Java)
Ответ 2
getDeclaredFields()
дает вам все поля этого класса, включая private
ones.
getFields()
дает вам все поля public
этого класса и его суперклассы.
Если вам нужны методы суперкласса private
/protected
, вам придется многократно вызывать getSuperclass()
, а затем вызвать getDeclaredFields()
в объекте Super Class.
Ничего здесь не ясно объяснено в javadocs
Ответ 3
попробуйте эти
Как прочитать приватное поле в Java?
Возможно ли в Java доступ к закрытым полям через отражение.
Field.setAccessible(true) - это то, что вам нужно сделать, чтобы сделать его доступным через отражение
import java.lang.reflect.Field;
class B
{
private int i = 5;
}
public class A extends B
{
public static void main(String[] args) throws Exception
{
A a = new A();
Field[] fs = a.getClass().getSuperclass().getDeclaredFields();
for (Field field : fs)
{
field.setAccessible(true);
System.out.println( field.get( a ) );
}
}
}
Ответ 4
Чтобы получить поля суперкласса, используйте getSuperclass()
. Оттуда вы можете получить поля суперкласса.
Ответ 5
ClassName obj = new ClassName();
Field field = ClassName.class.getDeclaredField ("name of the field");
field.setAccessible (true);
DataType value = (DataType) field.get (obj);
Перед извлечением значения вы должны использовать setAccessible в true. Когда-то JVM не позволяет извлекать приватную переменную, это может привести к исключению безопасности.
Ответ 6
Ранее спрашивали.
Доступ к приватным унаследованным полям через отражение в Java
В вашем коде установите field.setAccessible(true);
Ответ 7
Вот метод, который я использую для получения всех полей объекта
private <T> List<Field> getFields(T t) {
List<Field> fields = new ArrayList<>();
Class clazz = t.getClass();
while (clazz != Object.class) {
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
return fields;
}
Ответ 8
Да, возможно использование Reflection.
В вашем коде Field.setAccessible(true);
Идите и изучите концепцию, но НЕ делайте этого: -)