【问题标题】:how to get a constant in java with class如何在java中使用类获取常量
【发布时间】:2011-02-21 07:38:49
【问题描述】:

基本上我需要为一个类获取一个常量,但是我没有对象的实例,只有它的类。 在 PHP 中我会做 constant(XYZ); 有没有类似的方式在 JAVA 中检索常量?

我需要它来促进动态 getMethod 调用

Class parameterType = Class.forName(class_name);
object.setProperty(field name, field value, parameterType);

set 属性方法然后会获取正确的方法并设置指定的属性,但是我无法在不使用 Interger.TYPE 的情况下获取具有 int 作为参数类型的方法

【问题讨论】:

    标签: java reflection dynamic constants


    【解决方案1】:

    你可能会寻找某事。喜欢
    Foo.class.getDeclaredField("THIS_IS_MY_CONST").get(null); 要么 Class.forName("Foo").getDeclaredField("THIS_IS_MY_CONST").get(null); (感谢f-o-o

    获取类 Foo 中的字符串常量 (THIS_IS_MY_CONST) 的值。

    更新 使用null 作为get 的参数,谢谢acdcjunior

    【讨论】:

    • 请注意,传递给Field#get(Object) 方法的String.class 参数对于静态字段没有实际意义——根据javadoc: > 如果基础字段是静态字段,则忽略obj 参数;它可能为空。所以该参数并不意味着该字段值将是一个字符串并且可以为空。
    • 因为它是一个static 字段,所以Foo.class.getDeclaredField("MY_CONST").get(null); 是获取其值的正确方法。 (答案中的 String.class 参数被忽略,实际上具有误导性。)
    • 如果你不知道 Foo 是什么?我认为 Class.forName("Foo") 会更理想。
    【解决方案2】:

    如果这个常量是关于类的元数据,我会使用annotations

    第一步,声明注解:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @interface Abc {
        String value(); 
    }
    

    第二步,注释你的类:

    @Abc("Hello, annotations!")
    class Zomg {
    
    }
    

    第三步,取值:

    String className = "com.example.Zomg";
    Class<?> klass = Class.forName(className);
    Abc annotation = klass.getAnnotation(Abc.class);
    String abcValue = annotation.value();
    System.out.printf("Abc annotation value for class %s: %s%n", className, abcValue);
    

    输出是:

    Abc注解值:Hello,注解!

    【讨论】:

      【解决方案3】:

      我不确定你想得到什么。不过举个例子应该不会太难。

      假设您有一个带有属性栏的 Foo 类。

      Class Foo {
          private final String bar = "test";
          public String getBar() {return bar;}
      }
      

      现在要通过反射得到这个,你会:

      Class fooClass = Foo.class;
      Object fooObj = fooClass.newInstance();
      Method fooMethod = fooClass.getMethod("getBar");
      String bar = (String) fooMethod.invoke(fooObj);
      

      现在您将在 bar 变量中获取方法 getBar() 的值

      【讨论】:

        【解决方案4】:

        也许我不明白您需要什么,但您是否尝试过使用 final 静态属性和静态方法?

        Final 表示一旦设置就不能更改,所以你得到一个常量。 静态意味着即使没有任何类对象也可以访问它。

        【讨论】:

          【解决方案5】:

          如果您不想实际加载或初始化类,ClassGraph 可以这样做:

          String fieldVal;
          try (ScanResult scanResult =
                  new ClassGraph().whitelistClasses(className).enableFieldInfo().scan()) {
              fieldVal = (String) scanResult.getClassInfo(className).getFieldInfo("s")
                      .getConstantInitializerValue();
          }
          

          注意这仅适用于分配给静态最终字段常量初始化器值(可以在没有对象实例化的情况下计算的值,String 除外)。编译器可以在编译时为简单的算术和简单的字符串连接生成一个常量。

          (免责声明,我是ClassGraph的作者)

          如果您不介意加载类,只需使用反射来访问静态字段会更简单,如另一个答案中所述:https://stackoverflow.com/a/4076792/3950982

          【讨论】:

            【解决方案6】:

            获取私有常量,如:

            private static final String BAR = "test";
            

            您需要先将其设置为可访问:

            Field barField = Foo.class.getDeclaredField("BAR");
            barField.setAccessible(true);
            String bar = (String) barField.get(null);
            

            【讨论】:

              猜你喜欢
              • 2016-02-29
              • 1970-01-01
              • 2019-03-08
              • 1970-01-01
              • 1970-01-01
              • 2013-09-17
              • 1970-01-01
              • 2012-09-13
              • 1970-01-01
              相关资源
              最近更新 更多