tags:

views:

90

answers:

2

Hi,

I have several interfaces all with the same constants - ID and ROOT. I also have a method into which I pass an object that will be an implementation of one of these interfaces.

How can I dynamically retrieve the value of the constant depending on the class passed in - i.e. I want to do something like the following:

public void indexRootNode(Node node, Class rootNodeClass)
{
    indexService.index(node, rootNodeClass.getConstant('ID'), 
        rootNodeClass.getConstant('ROOT'));
}

In PHP this is easy, but is this possible in Java? I've seen this problem solved using accessors on the constant, but I want to retrieve the constant directly. Annotations won't help me here either.

Thanks

+5  A: 

This can be achieved using reflection (also see corresponding javadoc).

public void indexRootNode(Node node, Class rootNodeClass)
{
    Field idField = rootNodeClass.getField("ID");
    Object idValue = idField.get(null);
    Field roorField = rootNodeClass.getField("ROOT");
    Object rootValue = rootField.get(null);

    indexService.index(node, idValue, rootValue);
}

Maybe you may additionaly have to cast the values to the corresponding type.

inflagranti
great, thanks a lot
Michael Jones
A: 

Please read chapter 19 use interfaces only to define types from Joshua Bloch's Effective Java (in fact, please read the entire book)

Constants do not belong in an interface!!! Constants should be tied to implementing classes, not interfaces.

Either use non-constant methods:

// the implementing classes can define these values
// and internally use constants if they wish to
public interface BaseInterface{
    String id(); // or getId()
    String root(); // or getRoot()
}

public interface MyInterface1 extends BaseInterface{
    void myMethodA();
}

public interface MyInterface2 extends BaseInterface{
    void myMethodB();
}

or use an enum to tie things together:

public enum Helper{

    ITEM1(MyInterface1.class, "foo", "bar"),
    ITEM2(MyInterface2.class, "foo2", "baz"),
    ;

    public static String getId(final Class<? extends BaseInterface> clazz){
        return fromInterfaceClass(clazz).getId();

    }

    public static String getRoot(final Class<? extends BaseInterface> clazz){
        return fromInterfaceClass(clazz).getRoot();
    }

    private static Helper fromInterfaceClass(final Class<? extends BaseInterface> clazz){
        Helper result = null;
        for(final Helper candidate : values()){
            if(candidate.clazz.isAssignableFrom(clazz)){
                result = candidate;
            }
        }
        return result;
    }

    private final Class<? extends BaseInterface> clazz;

    private final String root;

    private final String id;

    private Helper(final Class<? extends BaseInterface> clazz,
        final String root,
        final String id){
        this.clazz = clazz;
        this.root = root;
        this.id = id;

    };

    public String getId(){
        return this.id;
    }

    public String getRoot(){
        return this.root;
    }

}

// use it like this
String root = Helper.fromInterfaceClass(MyInterface1.class).getRoot();
seanizer