2016-06-02 3 views
-1

I имеют следующую структуру для большого проекта Java:Java: Изменение значения статической переменной по имени класса строки

Class BigParentClass 
{ 
... 
}; 

И тогда многие классы, расширяющие этот BigParentClass, все из которых имеют ту же статическую переменную ,

Class A extends BigParentClass 
{ 
    static boolean importantVal = false; 
}; 

Class B extends BigParentClass 
{ 
    static boolean importantVal = false; 
} 
..etc.. 

Что мне нужно сделать, это, во время инициализации, я буду получать список имен класса строк, в которых мне нужно установить статическую переменную importantVal в TRUE. Поэтому я получить список таких как:

"A, C, F, K"

и мне нужен способ, в котором можно изменить статическую переменную для классов A, C, F, K в TRUE. Каким был бы способ сделать это?

Я пытался сделать что-то вроде:

Class strToClass = Class.forName(classNameString); 

Однако, нет никакой возможности ссылаться на «importantVal» статическую переменную без литья этой переменной класса до фактического класса, который имеет его.

Class class = Class.forName(classNameString); 
switch(class) 
{ 
    case A: 
     (A)class.importantVal = true; 
     break; 
    case B: 
     (B)class.importantVal = true; 
     break; 
    ..etc.. 
} 
+3

Похоже, вы пытаетесь сделать что-то очень странное. Почему вы хотите изменить переменную? Какая картина? – Kayaman

+0

Мне нужно сделать что-то по-другому на основе этого значения, и это значение может быть изменено внешним источником (я бы получил файл с именами классов, которые требуют, чтобы это было изменено). Единственный другой вариант - при выполнении фактического рендеринга сравнить текущий класс с этим списком, но это потенциально большой список, и рендеринг и повторный рендеринг происходят довольно часто. – Tesla

ответ

1

Вы можете просто использовать метод getDeclaredField и set на самом объекте класса, так как это: мне нужно просто сократить свои потери, и есть переключатель заявление для всех моих классов, что делает изменения, что нужно делать статическое поле.

Class<?> clazz = Class.forName("MyClass"); 
clazz.getDeclaredField("importantVal").set(null, true); 

Таким образом, в пределах вашей итерации:

for (String fullyQualifiedClassName: myIterable) { 
    try { 
     Class 
      .forName(fullyQualifiedClassName) 
      .getDeclaredField("importantVal").set(null, true); 
    } 
    // java 7 idiom here to simplify 
    catch (ClassNotFoundException | NoSuchFieldException | 
      IllegalAccessException | IllegalArgumentException e) { 
     // TODO handle 
    } 
} 
+1

Разве это не 'set (null, true)'? –

+0

@ AndyTurner на самом деле оба идиома, похоже, работают. – Mena

+0

["Если базовое поле является статическим, аргумент obj игнорируется, он может быть null."] (Https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field. html # set (java.lang.Object,% 20java.lang.Object)) Итак, да, либо работайте. Я предпочитаю нуль, поскольку похоже, что вы устанавливаете поле в экземпляре 'Class' в противном случае. –

0

Это пахнет плохой дизайн. Вместо того, чтобы устанавливать поля других классов, пусть каждый класс устанавливает свое собственное значение, потянув исходную конфигурацию:

public class InitialConfig { 
    public static Collection<String> importantValueEnabledClassNames() { 
     // Read class name strings here 
    } 
} 

public class A extends BigParentClass { 
    static final boolean importantVal = 
     InitialConfig.importantValueEnabledClassNames().contains(
      A.class.getName()); 
} 

public class B extends BigParentClass { 
    static final boolean importantVal = 
     InitialConfig.importantValueEnabledClassNames().contains(
      B.class.getName()); 
} 
Смежные вопросы