有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

package example.package;

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

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


共 (2) 个答案

  1. # 1 楼答案

    使用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();
    }
    
  2. # 2 楼答案

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

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

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