Lex Webb
Lex Webb

Reputation: 2852

Java Reflection get declared fields of unknown type SubClass

I am writing a packet class that will hopefully be able to take all the declared fields of its SubClasses, add them to a list and then send them across the network.

Packet SuperClass:

public class TCPacket {
private PacketType packetType;
private List<Object> packetData = new ArrayList<Object>();

public TCPacket(PacketType type){
    this.packetType = type;
    packetData.add(type.getIdent());
}

public PacketType getType(){
    return packetType;
}

public List<Object> getDataList(){
    return packetData;
}

public ByteArrayOutputStream getDataOS() throws IOException{
    //writes data to stream
}

public void addData(Object object){
    this.packetData.add(object);
}

private void addDeclaredFields(){
    Field[] fields = this.getClass().asSubclass(this.getClass()).getDeclaredFields();

    for(Field field : fields)
        this.packetData.add(field);
}
}

The important line in this is:

Field[] fields = this.getClass().asSubclass(this.getClass()).getDeclaredFields();

My hope, is that with this, i will be able to get all the declared fields of the SubClass ONLY, regardless of the SubClass type.

Obviously i could do something like this:

Field[] fields = this.getClass().asSubclass(PacketRequestLogon.class).getDeclaredFields();

but i'd rather not hard code every packet type. What i am really asking, is will this.getClass() return the SubClass IF the method containing it: addDeclaredFields() is called from within the SuperClass, or will it return the super.

Upvotes: 0

Views: 2562

Answers (1)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

My hope, is that with this, i will be able to get all the declared fields of the SubClass ONLY, regardless of the SubClass type.

From Class#getDeclaredFields jadavoc (emphasis mine):

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.

So you can be sure you're not getting the fields from the super class.


Tested your current implementation of addDeclaredFields:

class ASuperClass {
    protected int fieldInASuperClass;
    public final void addDeclaredFields(){
        Field[] fields = this.getClass().asSubclass(this.getClass()).getDeclaredFields();
        for(Field field : fields) {
            //edited this line for test purposes
            System.out.println(field.getName());
        }
    }
}

class ASubClass extends ASuperClass {
    private int fieldInASubClass;
}

class AnotherSubClass extends ASuperClass {
    private int fieldInAnotherSubClass;
    private int justAnotherFieldInAnotherSubClass;
}

public class AMainClass {
    public static void main(String[] args) {
        new ASuperClass().addDeclaredFields();
        System.out.println("--------------------------------------");
        new ASubClass().addDeclaredFields();
        System.out.println("--------------------------------------");
        new AnotherSubClass().addDeclaredFields();
    }
}

Prints:

fieldInASuperClass
--------------------------------------
fieldInASubClass
--------------------------------------
fieldInAnotherSubClass
justAnotherFieldInAnotherSubClass

Note that only prints the declared fields of the subclass, the inherited fields are not printed.

Upvotes: 1

Related Questions