【问题标题】:How do I get a variable value from a String in Java?如何从 Java 中的字符串中获取变量值?
【发布时间】:2021-08-09 15:19:26
【问题描述】:

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

package example.package;

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

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

【问题讨论】:

  • 您可以添加更多上下文吗?您如何尝试使用 bukkit 指定字符串?你指定引号了吗?如果是这样,也许他们应该被删除?
  • 请注意,Java 中的标准是将常量命名为全大写,例如 FOO
  • @chrylis-cautiouslyoptimistic- 不是全大写只适用于常量吗?
  • @KarthikeyanVaithilingam 你是对的,我错过了这不是声明final。 OP,拥有不是最终的静态变量几乎总是一个问题。
  • 我认为您正在寻找 Reflection 是吗?

标签: java bukkit


【解决方案1】:

example.package.Ex.foo 将返回bar,正如您所提到的。静态变量由类而不是实例拥有,因此只有一个变量副本存在,您不需要创建实例。

如果你想在同一个类中访问变量,只需在变量名中使用它,如果你想在另一个类中使用它,你可以使用多种方式。

  1. 通过变量的完全限定名。
    package another.pack;
    
    public class AnotherClass {
       public void testVar(){
           String tempStr = example.package.Ex.foo;
       }
    }
    
  2. 导入类并使用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";
}

注意:惯例是对常量使用大写。

【讨论】:

  • 是的,但我想从字符串中获取它
【解决方案2】:

使用 java 11(Reflection 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();
}

【讨论】:

    猜你喜欢
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多