Search code examples
javabukkit

How do I get a variable value from a String in Java?


So I am writing a debugger plugin for Minecraft bukkit and I was wondering how to get a public static variable value from a String. Here is some example code:

package example.package;

public class Ex {
 public static String foo = "bar";
}

If I were to give it the string "example.package.Ex.foo" it should return "bar", how do I do this?


Solution

  • using java 11(Reflection API) - you can do this in older java versions too

    public class Main {
        public static void main(String[] args) {
            var _this = new Main();
            _this.doJob();
        }
        
        void doJob() {
            var classLoader = this.getClass().getClassLoader();
            try {
                var loaded = classLoader.loadClass("example.package.Ex");
                var obj = new Object();
                var field = loaded.getField("foo");
                System.out.println(field.get(obj));
            } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    

    Edit A generic approach would be like this:

    <T> T getFieldValueAtRuntime(String field) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        var classLoader = this.getClass().getClassLoader();
        final var endIndex = field.lastIndexOf('.');
        final var fullClassName = field.substring(0, endIndex);
        final var fieldName = field.substring(endIndex + 1);
        var loadedClass = classLoader.loadClass(fullClassName);
        var obj = new Object();
        var fieldOfLoadedClass = loadedClass.getField(fieldName);
        return (T) fieldOfLoadedClass.get(obj);
    }
    -------------------------
    try {
        String fieldValue = _this.getFieldValueAtRuntime("example.package.Ex.foo");
        System.out.println(fieldValue);
    } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }