2013-06-11 8 views
6

Mam kod, który ustawia wartości na obiekcie za pomocą jego metod Setter. Jeden z setterów przyjmuje jako typ metody parametr Enum. Kod wygląda tak:Jak przekonwertować ciąg do wartości wyliczeniowej, gdy typ odniesienia enum jest klasą <?>?

String value = "EnumValue1"; 
    Method setter = getBeanWriteMethod("setMyEnumValue"); 
    Class<?> type = setter.getParameterTypes()[0]; 
    Object convertedValue = null; 
    if (type.isEnum()) { 
     convertedValue = convertToEnum(value, type); 
    } else { 
     convertedValue = ClassUtils.convertType(value, type); 
    } 
    return convertedValue; 

Pytanie brzmi, co umieścić w metodzie convertToEnum. Wiem, że mogłem "brutalnie wymusić" przez iterację stałych enum (lub pól) obiektu, dopasowując wartość. Czy mogę przeoczyć prostszy sposób na zrobienie tego za pomocą Reflection? (Spojrzałem na kilka przykładów, ale nie znalazłem żadnego miejsca, w którym enum było znane tylko przez klasę).

Odpowiedz

19

Off szczycie mojej głowie:

Enum<?> convertedValue = Enum.valueOf((Class<Enum>)type, value); 

To będzie przekonwertować ciąg do stałej enum klasy Enum typu

Edycja: Teraz mam komputer poręczny, ja widzę, co faktycznie działa. Każda z poniższych przypadków prowadził poprawnie bez ostrzeżenia kompilatora:

Enum<?> convertedValueA = Enum.valueOf(type, value); 
Enum<?> convertedValueB = Enum.valueOf(type.asSubclass(Enum.class), value); 

Drugi nazywa asSubClass(), która zrobi kontrolę wykonania w celu zapewnienia, że ​​type pewne klasy enum, ale metoda valueOf() musi zrobić to sprawdzić w każdym razie aby działać poprawnie.

Poniższa dał mi błąd kompilacji:

Enum<?> convertedValueC = Enum.valueOf((Class<? extends Enum <?>>)type, value); 

java: Foo.java:22: <T>valueOf(java.lang.Class<T>,java.lang.String) in java.lang.Enum cannot be applied to (java.lang.Class<capture#134 of ? extends java.lang.Enum<?>>,java.lang.String) 

zawiłości odlewania do wieloznacznych typów mylą mnie więc już prawdopodobnie próbował złą obsadę. Ponadto fakt, że nie ma on żadnego efektu runtime, oznacza, że ​​łatwo jest go pomylić i nigdy się nie dowiedzieć.

+0

Dzięki, musiałem złapać obsadę źle, gdy po raz pierwszy spróbowałem. To jest poprawne rozwiązanie. Niestety, po wypróbowaniu tego, stwierdziłem, że muszę zrobić dopasowanie niewrażliwe na wielkość liter, które 'Enum.valueOf()' nie zrobi. Wracając do podejścia brutalnej siły ... –

+0

Ten przypadek jest okropny. "typ" nie jest "Enum.class". W każdym razie 'asSubclass' jest lepsza niż rzut hackowy. –

+0

@ TomHawtin-tackline: użycie jako 'asSubclass' daje mi ostrzeżenia kompilatora. 'Klasa enumClass = type.asSubclass (Enum.class); Enum convertValue = Enum.valueOf (enumClass, "Value1"); 'dla obu typów Raw, a także Unvhecked Invocation. Więc nie jestem pewien, czy widzę, jak to jest lepsze. –

1
Enum.valueOf(yrEnum, myString) 

Powoduje wybranie wyliczenia, w którym myString jest nazwą instancji wyliczeniowej. I yrEnum.values() zwraca tablicę wszystkich możliwych instancji Emotions.

+0

Podobnie jak poprzednie, oddanych do klasy jest wymagane do tej pracy. –

4

Można użyć

Class enumType = .... 
String name = .... 

Enum e = Enum.valueOf(enumType, name); 

np

import java.lang.annotation.*; 

public class Main { 
    public static void main(String[] args) { 
     Class enumType = RetentionPolicy.class; 
     String name = "SOURCE"; 

     Enum e = Enum.valueOf(enumType, name); 
     System.out.println(e); 
    } 
} 

drukuje

SOURCE 
+0

To wymaga obsady, którą Adrian umieścił powyżej. –

+0

@SamGoldberg To typ surowy. Myślę więc, że to zadziała. Po prostu źle. –

+0

@ TomHawtin-tackline: Nie mogę go skompilować bez obsady. –

Powiązane problemy