如何从 Java 中的字符串获取变量值?

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

所以我正在为 Minecraft bukkit 编写调试器插件,我想知道如何从字符串中获取 public 静态变量值。这是一些示例代码:

package example.package;

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

如果我给它字符串“example.package.Ex.foo”,它应该return“bar”,我该怎么做?

如您所述,

example.package.Ex.foo 将 return bar。静态变量由 class 而不是实例拥有,因此只有一个变量副本存在,您不需要创建实例。

如果你想在同一个 class 中访问变量,如果你想在另一个 class 中使用它,只需通过变量的名称使用它,你可以使用多种方法。

  1. 通过变量的完全限定名称。
    package another.pack;
    
    public class AnotherClass {
       public void testVar(){
           String tempStr = example.package.Ex.foo;
       }
    }
    
  2. 导入 class 并使用 class.variable。
    package another.pack;
    
    import example.package.Ex;
    
    public class AnotherClass {
       public void testVar(){
           String tempStr = Ex.foo;
       }
    }
    
  3. 静态导入。
    package another.pack;
    
    import static example.package.Ex.foo;
    
    public class AnotherClass {
       public void testVar(){
           String tempStr = foo;
       }
    }
    

在上述所有示例中,tempStr 的值将是 "bar"

由于变量只有一个副本退出,所以你必须小心,如果变量在一个地方被改变,它会影响到所有地方。

如果你想要一个常量,在声明变量时使用 final 关键字

package example.package;

public class Ex {
 public static final String FOO = "bar";
}

Note: the convention is to use upper case for constants.

使用 java 11(反射 API)- 您也可以在旧 java 版本中执行此操作

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();
        }
    }
}

编辑 通用方法是这样的:

<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();
}