2016-11-21 2 views
0

Мне нужно найти способ использования String для получения значения переменной в другом классе. Например, скажем, у меня был этот класс:Использование String для поиска статической переменной Java

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

И я также имел эту строку в другом классе:

String str = "ClassName.f"; 

Есть ли способ, которым я мог бы использовать строки, ул, чтобы получить значение от ClassName.f? Я не хочу, чтобы каждый код привязывался к конкретному методу.

+0

Вы ищете отражение. Однако, скорее всего, вы должны использовать карту. – SLaks

+0

Как бы вы это использовали? – user6615347

+0

Карта строк для классов? –

ответ

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; 
    } 
} 
0

Использование 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 
0

Карта, как предложено в комментариях, может быть вашим лучшим выбором, так как в этом случае отражение может быть не лучшей практикой.

Чтобы иметь возможность звонить из любого места в вашей программе, вам нужно что-то вроде 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); 

Двойная проверка одноэлементного шаблона для реализации. Если это звучит слишком много, тогда могут быть другие доступные опции, но вы не указали много контекста или цели вашего приложения, так что это зависит.

Смежные вопросы