2013-06-11 10 views
6

Ho un codice che sta impostando i valori su un oggetto usando i suoi metodi setter. Uno dei setter prende un tipo Enum come parametro del metodo. Il codice simile a questa:Come convertire String in enum value quando enum type reference è una classe <?>?

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; 

La domanda è: cosa mettere nel metodo convertToEnum. So che potrei "forzare la forza" iterando le costanti di enum (oi campi) dell'oggetto type, facendo corrispondere il valore. Sto trascurando un modo più semplice di farlo usando Reflection? (Ho esaminato diversi esempi, ma non ho trovato nessuno in cui l'enum fosse noto solo tramite Class).

risposta

19

Fuori della parte superiore della mia testa:

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

Ciò convertire una stringa in una costante enum della classe Enum di tipo

Edit: Ora che ho un computer a portata di mano, ho può vedere cosa funziona davvero. In entrambi i casi al di sotto corse correttamente senza avvisi del compilatore:

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

Il secondo si chiama asSubClass(), che avrebbe fatto un controllo di runtime per garantire che type è una certa classe enum, ma il metodo valueOf() deve fare che il check in ogni caso per funzionare correttamente.

Di seguito mi ha dato un errore di compilazione:

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) 

La complessità di colata a tipi jolly confonde me, così ho provato probabilmente il cast sbagliato. Inoltre il fatto che non ha effetti di runtime significa che è facile sbagliare e non scoprirlo mai.

+0

Grazie, devo aver sbagliato il cast quando l'ho provato per la prima volta. Questa è la soluzione corretta. Sfortunatamente, dopo aver provato questo, ho scoperto che ho bisogno di fare una corrispondenza insensibile alle maiuscole e minuscole, che 'Enum.valueOf()' non farà. Quindi torniamo all'approccio della forza bruta ... –

+0

Quel caso è orribile. 'type' non è' Enum.class'. In ogni caso, 'asSubclass' è meglio di un cast di hack. –

+0

@ TomHawtin-tackline: l'utilizzo di 'asSubclass' mi dà gli avvisi del compilatore. 'Class enumClass = type.asSubclass (Enum.class); Enum convertedValue = Enum.valueOf (enumClass, "Value1"); 'sia per Raw Type che Invocation non verificato. Quindi non sono sicuro di vedere come sia migliore. –

1
Enum.valueOf(yrEnum, myString) 

Restituisce l'enum dove myString è il nome dell'istanza di enum desiderata. E yrEnum.values() restituisce una matrice di tutte le diverse istanze di Enum possibili.

+0

Come precedente, il cast di classe è necessario per fare questo lavoro. –

4

È possibile utilizzare

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

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

esempio

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

stampe

SOURCE 
+0

Questo ha bisogno del cast che Adrian ha messo sopra per funzionare. –

+0

@SamGoldberg Questo è un tipo non elaborato. Quindi penso che funzionerà. Proprio male. –

+0

@ TomHawtin-tackline: non riesco a farlo compilare senza il cast. –

Problemi correlati