Invoke Java object constant using a variable

icecub :

I'm very new to Java so it makes it hard for me to explain what I'm trying to do.

I have an abstract class that invokes several object constants like this:

public abstract class Enchantment implements Keyed {
    /**
     * Provides protection against environmental damage
     */
    public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper("protection");

In a different file I can access this perfectly fine with
Enchantment value = Enchantment.PROTECTION_ENVIRONMENTAL;

However, I'm trying to use a string variable for this instead. Something like this:

String str = "PROTECTION_ENVIRONMENTAL";
Enchantment value = Enchantment.str;

Obviously that won't work. So I did a bunch of research and learned I need to use reflection for this. Using this source code's docs I figured I was looking for field data. So I tried both:

Field fld = Enchantment.class.getField("PROTECTION_ENVIRONMENTAL");
Field fld = Enchantment.class.getDeclaredField("PROTECTION_ENVIRONMENTAL");

But these returned me a NoSuchFieldException. As I was on it, I've tried both getMethod() and getDeclaredMethod() just as well equally with no luck.

I'm now at the point that these are probably "object constants"? I'm not sure how to call them. But I'm definitely at a loss on how to get this to work now and after everything I've tried myself, I figured it was time to ask for some help here.

Elliott Frisch :

Once you have the Field, you need to call Field.get(Object) with an instance (in this case the class). Something like,

Class<?> cls = Enchantment.class;
try {
    Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
    System.out.println(f.get(cls));
} catch (Exception e) {
    e.printStackTrace();
}

Since you want the Enchantment, you could then test that the instance you get is assignable to Enchantment. Something like,

Class<? extends Enchantment> cls = Enchantment.class;
try {
    Field f = cls.getField("PROTECTION_ENVIRONMENTAL");
    Object obj = f.get(cls);
    if (cls.isAssignableFrom(obj.getClass())) {
        Enchantment e = cls.cast(obj);
        System.out.println(e);
    }
} catch (Exception e) {
    e.printStackTrace();
}

But the enum approach is better.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=308936&siteId=1