【问题标题】:Using a String to find a static variable Java使用字符串查找静态变量 Java
【发布时间】:2016-11-21 15:31:54
【问题描述】:

我需要找到一种在另一个类中使用字符串来获取变量值的方法。例如,假设我有这个课程:

public class ClassName {
   public static File f = new File ("C:\\");
}

而且我在另一个类中也有这个字符串:

String str = "ClassName.f";

有没有一种方法可以使用字符串 str 来获取 ClassName.f 的值?我不想将每个值硬编码到特定的方法中。

【问题讨论】:

  • 您正在寻找反射。但是,您可能应该改用地图。
  • 你会如何使用它?
  • 字符串到类的映射?
  • String str=ClassName.f; 这应该可以工作
  • @XtremeBaumer 什么?

标签: java string class variables


【解决方案1】:

假设您始终只需要静态字段,以下代码会进行一些字符串拆分并使用反射来执行此操作。运行时会打印“oy”...

import java.lang.reflect.Field;

public class StackOverflow {

    public static String oy = "OY";

    public static void main(String[] args) {
        System.out.println(getStaticValue("StackOverflow.oy"));
    }

    public static Object getStaticValue(String fieldId) {
        int idx = fieldId.indexOf(".");
        String className = fieldId.substring(0, idx);
        String fieldName = fieldId.substring(idx + 1);

        try {
            Class<?> clazz = Class.forName(className);
            Field field = clazz.getDeclaredField(fieldName);
            return field.get(null);
        } catch(Exception ex) {
           // BOOM!
            ex.printStackTrace();
        }

        return null;
    }
}

如果您的静态字段不是公开的,则需要使其可访问,为此,您需要添加“setAccessible”行...

import java.lang.reflect.Field;

public class StackOverflow {

    private static String oy = "OY";

    public static void main(String[] args) {
        System.out.println(getStaticValue("StackOverflow.oy"));
    }

    public static Object getStaticValue(String fieldId) {
        int idx = fieldId.indexOf(".");
        String className = fieldId.substring(0, idx);
        String fieldName = fieldId.substring(idx + 1);

        try {
            Class<?> clazz = Class.forName(className);
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(null);
        } catch(Exception ex) {
           // BOOM!
            ex.printStackTrace();
        }

        return null;
    }
}

【讨论】:

    【解决方案2】:

    使用reflection:

    // make array to use easier
    String[] str = "ClassName.f".split("\\.");
    
    // get the class
    Class c = Class.forName("packagename." + str[0]);
    // get the field
    Field field = c.getDeclaredField(str[1]);
    
    // USE IT!
    System.out.println(field.getName());
    

    输出:

    f
    

    【讨论】:

      【解决方案3】:

      按照 cmets 的建议,地图可能是您的最佳选择,因为在这种情况下,反射可能不是最佳做法。

      为了能够从程序中的任何位置调用它,您需要像 Singleton 模式这样的东西,必须小心处理:

      public class ClassNameHandler {
         private static ClassNameHandler instance = null;
         protected ClassNameHandler() {
            // Exists only to defeat instantiation.
         }
      
         public Map<String, File> map = new HashMap<String, File>();
      
         public File f = ClassName.f;
         map.put("ClassName.f", f);
         //Add more files or variables to the map
      
         public static ClassNameHandler getInstance() {
            if(instance == null) {
               instance = new ClassNameHandler();
            }
            return instance;
         }
      }
      

      然后,在其他地方,你可以使用类似的东西:

      String str = "ClassName.f";
      ClassNameHandler.map.get(str);
      

      仔细检查单例模式的实现。如果听起来太多,那么可能还有其他可用选项,但您没有提供太多上下文或应用程序的目的是什么,所以这取决于。

      【讨论】:

        【解决方案4】:

        我需要这样的东西作为通过 Android 应用程序将 api 密钥注入 Unity3d 的一部分

        感谢我在这里找到的一些答案:

        OnCreate

        tryPutExtra("SECRET_API_STUFF");
        

        tryPutExtra函数

        void tryPutExtra(String prop) {
            try {
                Field field = BuildConfig.class.getDeclaredField(prop);
                String str = String.valueOf(field);
                getIntent().putExtra(prop, str);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        

        ** 编辑 **

        在某些时候,上述功能停止工作,我不知道为什么。我已迁移到以下位置:

            try {
                Field field = BuildConfig.class.getDeclaredField(prop);
                // String str = String.valueOf(field);
                String str = field.get(null).toString();
                intent.putExtra(prop, str);
                Log.i(null, "PutExtra " + prop + " = " + str);
                field.setAccessible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        

        【讨论】:

          猜你喜欢
          • 2011-02-17
          • 1970-01-01
          • 2016-02-02
          • 2018-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-09
          • 1970-01-01
          相关资源
          最近更新 更多