簡體   English   中英

使用字符串查找 static 變量 Java

[英]Using a String to find a static variable Java

我需要找到一種方法來使用字符串來獲取另一個 class 中的變量值。例如,假設我有這個 class:

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

我還在另一個 class 中有這個字符串:

String str = "ClassName.f";

有沒有一種方法可以使用字符串 str 來獲取 ClassName.f 的值? 我不想將每個值硬編碼到特定方法中。

假設您始終只需要靜態字段,下面的代碼將進行一些字符串拆分,並使用反射進行此操作。 運行時它將顯示“ 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;
    }
}

使用反射

// 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

評論中建議的地圖可能是您最好的選擇,因為在這種情況下,反思可能不是最佳實踐。

為了能夠從程序的任何地方調用它,您需要類似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);

仔細檢查單例模式的實現。 如果聽起來太多,那么可能還有其他選項可用,但是您沒有提供太多上下文或應用程序的用途是什么,所以這取決於。

我需要這樣的東西作為通過 Android 應用程序將 api 密鑰注入 Unity3d 的一部分

感謝這里的一些答案,我想出了:

OnCreate里面

tryPutExtra("SECRET_API_STUFF");

tryPutExtra function

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

** 編輯 **

在某些時候,上面的 function 停止工作,我不知道為什么。 我已經遷移到以下內容:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM