it-swarm.com.de

Holen Sie sich alle Felder (auch privat und geerbt) aus der Klasse

Ich mache ein Universitätsprojekt.
Ich muss alle Felder aus dem Unterricht holen. Sogar privat und geerbt. Ich habe versucht, alle deklarierten Felder abzurufen und dann in die Superklasse zu wechseln und zu wiederholen. Fragment meines Codes:

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

Aber es funktioniert nicht. tmpObj ist nach dem Casting immer noch dieselbe Klasse (keine Superklasse).
Ich würde mich über jede Hilfe freuen, um das Casting-Problem zu beheben oder diese Felder auf andere Weise abzurufen.

Problem ist nicht, Zugriff auf Felder zu erhalten, sondern Namen von Feldern zu erhalten!
Ich schaffe es so:

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
49
Michał Herman
obj = obj.getClass().getSuperclass().cast(obj);

Diese Zeile entspricht nicht Ihren Erwartungen. Das Casting eines Object ändert es nicht wirklich, es weist den Compiler lediglich an, es als etwas anderes zu behandeln.

Z.B. Sie können ein List in ein Collection umwandeln, es bleibt jedoch weiterhin ein List.

Das Durchlaufen der Superklassen, um auf Felder zuzugreifen, funktioniert jedoch ohne Casting:

Class<?> current = yourClass;
while(current.getSuperclass()!=null){ // we don't want to process Object.class
    // do something with current's fields
    current = current.getSuperclass();
}

Übrigens, wenn Sie Zugriff auf das Spring Framework haben, gibt es eine praktische Methode zum Durchlaufen der Felder einer Klasse und aller übergeordneten Klassen:
ReflectionUtils.doWithFields(baseClass, FieldCallback)
(siehe auch meine vorherige Antwort: Zugriff auf private geerbte Felder über Reflection in Java )

78

getDeclaredFields() gibt Ihnen alle Felder dieser Klasse, einschließlich private.

getFields() gibt Ihnen alle public Felder dieser Klasse UND deren Oberklassen.

Wenn Sie private/protected Methoden von Superklassen wollen, müssen Sie getSuperclass() wiederholt aufrufen und rufen Sie dann getDeclaredFields() für das Objekt Super Class auf.

Nichts hier ist in den javadocs nicht klar erklärt

32
Tom McIntyre

Hier ist die Methode, die ich verwende, um alle Felder eines Objekts abzurufen

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;
    }
9
Adelin

probiere diese

Wie lese ich ein privates Feld in Java?

Ist es in Java möglich, über Reflection auf private Felder zuzugreifen

Field.setAccessible (true) ist das, was Sie tun müssen, um es über Reflection zugänglich zu machen

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 ) );
        }
    }
}
3
gurvinder372
ClassName obj  =  new ClassName();
Field field  =   ClassName.class.getDeclaredField  ("name of the field");
field.setAccessible   (true);
DataType value  =  (DataType) field.get  (obj);

Sie müssen setAccessible auf true setzen, bevor Sie den Wert extrahieren. Manchmal erlaubt JVM nicht, die private Variable zu extrahieren, es kann eine Sicherheitsausnahme geben.

1
Yatin Wadhawan

Zuvor gefragt.

Zugriff auf private geerbte Felder über Reflektion in Java

Setze in deinem Code field.setAccessible(true);

1
Maximin

Verwenden Sie getSuperclass(), um Felder der Oberklasse abzurufen. Von dort können Sie Felder der Oberklasse bekommen.

1
Vineet Singla

Diese Lösung verwendet Java 8 Streams, die für diejenigen nützlich sind, die das funktionale Programmieren in Java erlernen. Sie durchläuft getSuperclass und getDeclaredFields wie in den anderen Antworten angegeben, funktioniert jedoch auf funktionale Weise.

In der folgenden Zeile wird der Name jedes Feldnamens gedruckt, der in SomeClass oder einer seiner Oberklassen gefunden wurde.

allFieldsFor(SomeClass.class).map(Field::getName).forEach(System.out::println);

Hier ist der Code, der die Superklassen durchläuft, um den Datenstrom der Felder zu erstellen.

private Stream<Field> allFieldsFor( Class c ) {
    return walkInheritanceTreeFor(c).flatMap( k -> Arrays.stream(k.getDeclaredFields()) );
}

private Stream<Class> walkInheritanceTreeFor( Class c ) {
    return iterate( c, k -> Optional.ofNullable(k.getSuperclass()) );
}

Die folgende Methode wird von Streams.iterate modelliert, Streams.iterate ist jedoch so konzipiert, dass unendliche Streams erstellt werden. Diese Version wurde so geändert, dass sie endet, wenn Optional.none () von der Funktion fetchNextFunction zurückgegeben wird.

private <T> Stream<T> iterate( T seed, Function<T,Optional<T>> fetchNextFunction ) {
    Objects.requireNonNull(fetchNextFunction);

    Iterator<T> iterator = new Iterator<T>() {
        private Optional<T> t = Optional.ofNullable(seed);

        public boolean hasNext() {
            return t.isPresent();
        }

        public T next() {
            T v = t.get();

            t = fetchNextFunction.apply(v);

            return v;
        }
    };

    return StreamSupport.stream(
        Spliterators.spliteratorUnknownSize( iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE),
        false
    );
}
1
Chris K

Ja, mit Reflection ist das möglich.

In deinem Code setze Field.setAccessible(true);

Mach weiter und lerne das Konzept, aber tu es NICHT :-)

1
Geek