2

I was trying to implement something like enum by myself. While i was trying to iterate my constant objects i came across using reflection and i stumbled upon java.lang.reflect.Field . So here is my scenario. I have an entity class for holding a pair of String constants

public class ConstantEntity {

    private String constantName;
    private String constantDesc;

    ConstantEntity(String name, String desc) {
        this.constantName = name;
        this.constantDesc = desc;
    }

    public String constantName() {
        return this.constantName;
    }

    public String constantDesc() {
        return this.constantDesc;
    }

}

And I have a interface where i create the constants using the entity

public interface MyConstantsPool { 

    public static final ConstantEntity CONSTANT_ONE = new ConstantEntity("bla1", "11");
    public static final ConstantEntity CONSTANT_TWO = new ConstantEntity("bla2", "12");
    public static final ConstantEntity CONSTANT_THREE  = new ConstantEntity("bla3", "13");


}

And i am trying to consume and iterate through these constants using

import java.lang.reflect.Field;

public class ConsumeConstants {

    public static void main(String args[]) {

        Field[] fields = MyConstantsPool.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {

            Object myConstant = fields[i];
            ConstantEntity typeSafeEnum = (ConstantEntity) myConstant ;
            System.out.println(" The name: "
                    + ((ConstantEntity) typeSafeEnum).constantName());
            System.out.println(" The description: "
                    + ((ConstantEntity) typeSafeEnum).constantDesc());

        }
    }
}

I went through the documentation, but i couldn't grasp the idea behind Field. Am I completely wrong in the understanding of using reflection? When do we use Field? And what is the proper way to iterate through all the Object constants in the interface?

NOTE: I am using java 1.4; So i have to use basic java features to implement this.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
RBz
  • 896
  • 3
  • 17
  • 34

4 Answers4

1

Field is an accessor which lets you do set and get operations and also do examination, like discover the type or modifiers of the field at run-time.

And what is the proper way to iterate through all the Object constants in the interface?

If you want to iterate all the static ConstantEntity fields, you could use something like this:

Field[] fields = MyConstantsPool.class.getFields();
for (int i = 0; i < fields.length; i++) {
    Field f = fields[i];
    if ( ConstantEntity.class.isAssignableFrom(f.getType())
            && Modifier.isStatic(f.getModifiers()) ) {
        ConstantEntity constant =
            (ConstantEntity) f.get(null);
    }
}

Am I completely wrong in the understanding of using reflection?

From the mistake in your code, trying to cast myConstant directly to ConstantEntity, at least partially. You have to call get to actually retrieve the value held in the field. The Field object itself is just an accessor.

You may also see "What is reflection and why is it useful?"


Also, Java 1.4, really??? That's more than 10 years out of date.

Community
  • 1
  • 1
Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • 1
    Interfaces can't have non-static fields so `Modifier.isStatic(f.getModifiers()` is probably redundant (unless I misunderstood your idea). – Pshemo Apr 25 '16 at 18:17
  • @Pshemo Yes, you're right that checking the modifier here is more or less redundant. My code example is just intended to be a bit more general. – Radiodef Apr 25 '16 at 18:19
1

you just made simple error, you grab Field and tried to cast it to your class ConstantEntity,

you need to get value from field:

 Object myConstant = fields[i].get(null);
user902383
  • 8,420
  • 8
  • 43
  • 63
0

Using Java Reflection you can inspect the fields (member variables) of classes and get / set them at runtime.

Given an instance of a class, it is possible to use reflection to set the values of fields in that class. This is typically done only in special circumstances when setting the values in the usual way is not possible. Because such access usually violates the design intentions of the class, it should be used with the utmost discretion.

So a Class object can be used to obtain a Field object for a declared public, declared protected, or declared private field.

But, also in your case it could be useful for the 'design intention' of your interface.

granmirupa
  • 2,780
  • 16
  • 27
  • @Radiodef "I went through the documentation, but i couldn't grasp the idea behind Field. Am I completely wrong in the understanding of using reflection? When do we use Field?" I interpreted the question as: "why use reflection? when is useful? what is goal?" Was I wrong? – granmirupa Apr 25 '16 at 18:54
0

Why can't you just use arrays instead of reflection?

public static final ConstantEntity CONSTANT_ONE = new ConstantEntity("bla1", "11");
public static final ConstantEntity CONSTANT_TWO = new ConstantEntity("bla2", "12");
public static final ConstantEntity CONSTANT_THREE  = new ConstantEntity("bla3", "13");

public static final ConstantEntity[] CONSTANTS = {
    CONSTANT_ONE,
    CONSTANT_TWO,
    CONSTANT_THREE
};
gudok
  • 4,029
  • 2
  • 20
  • 30