Java Reflection für geerbte protected Klassenvariablen

stso

Mitglied
Hallo,
ist es mit java.lang.reflect möglich auf eine geerbte protected Variable zuzugreifen?

Ich hab zwei Klassen "AnAbstractClass" und "AClass":
Code:
public class AnAbstractClass
{
	protected int abstractField;
	public int publicAbstractField;

	public int getAbstractField() {
		return abstractField;
	}

	public void setAbstractField(int abstractField) {
		this.abstractField = abstractField;
	}
}

Code:
public class AClass extends AnAbstractClass
{
	private int field;

	public AClass(int field) {
		super();
		this.field = field;
	}

	public int getField() {
		return field;
	}

	public void setField(int field) {
		this.field = field;
	}
}

Nun möchte ich von ausserhalb auf die Variable "abstractField" in AnAbstractClass über AClass zugreifen. Ich weiß das ich auf alle in der Klasse deklarierten Variablen über Class.getDeclaredField() zugreifen kann. Für die variable "field" würde das so aussehen:
Code:
AClass aClass = new AClass(42);
Field field = aClass.getClass().getDeclaredField("field");

Jedoch für die geerbte Variable geht das nicht. Führe ich den untenstehenden Code aus, wird mir gesagt das es die Klassenvariable "abstractField" nicht gibt.
Code:
Field field = aClass.getClass().getDeclaredField("abstractField");

Mit der Methode getField() kann man leider nur auf die public Variablen zugreifen!?
Code:
Field field = aClass.getClass().getField("publicAbstractField");
Das geht - aber icht mit der protected Variable.

Gibt es eine Möglichkeit auf die Variable "abstractField" über das Class- Object der Klasse AClass zuzugreifen?
 
Hallo,

in dem Fall müsstest du es so machen.
Code:
Field field = aClass.getClass().getSuperclass().getDeclaredField("abstractField");

MFG

Sascha
 
Hallo Sascha,
viele Dank für deine Antwort! Wenn ich die JavaDoc richtig verstehe gibt getSuperclass() die direkte "Elternklasse" der aktuellen Klasse zurück? Wenn ich zum Beispiel auf eine Variable in "Object" zugreifen möchte müsste ich folgendes schreiben(?):
Code:
Field field = aClass.getClass().getSuperclass().getSuperclass().getDeclaredField("aField");
Und wenn ich auf Variablen einer beliebigen "Vorfahrklasse" zugreifen möchte?
Da muss ich mir wohl eine Methode Schreiben die alle Superklassen einer Klassen nach einer Variable durchsucht?
 
Hallo,

wenn du den Type doch sowieso schon weißt, kannst du denn doch auch explizit angeben.
Java:
/**
 * 
 */
package de.tutorials;

import java.lang.reflect.Field;

/**
 * @author Thomas.Darimont
 * 
 */
public class ReflectionExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Foo foo = new Foo();
        System.out.println(getFieldValueInContextOfClass(Foo.class,"barbar",foo));
        System.out.println(getFieldValueInContextOfClass(AbstractFoo.class,"bar",foo));
    }
    
    public static Object getFieldValueInContextOfClass(Class<?> clazz, String fieldName, Object instance) throws Exception{
        Field field = clazz.getDeclaredField(fieldName);
        return field.get(instance);
    }
    
    static class AbstractFoo{
        protected String bar ="bar";
    }
    
    static class Foo extends AbstractFoo{
        protected String barbar = "barbar";
    }

}

Gruß Tom
 
Ich möchte noch das gute Beispiel von Thomas um zwei wichtige Zeilen erweitern:

PHP:
    public static void main(String[] args) throws Exception {
        Foo foo = new Foo();
        System.out.println(getFieldValueInContextOfClass(Foo.class,"barbar",foo));
        System.out.println(getFieldValueInContextOfClass(AbstractFoo.class,"bar",foo));

        //System.out.println(getFieldValueInContextOfClass(Foo.class,"bar",foo)); // NoSuchFieldException ! Vergl. mit nächster Zeile
        System.out.println(getFieldValueInContextOfClass(Foo.class.getSuperclass(),"bar",foo));
    }

Noch eine weitere Anmerkung mit Protected: Problem bei mir war noch, dass der Compiler sagte:
can not access a member of class XYZ.ABC with modifiers "protected"

Lösung war: die andere Klasse hatte ich zum Herumprobieren irgendwann mal dummerweise in ein anderes Package gelegt. Musste die Klasse ins gleiche package packen, dann gings wieder :-)
 
Zuletzt bearbeitet:
Zurück