java: Reflexion, um ein Enum zu erhalten

8

Dies ist ähnlich, aber nicht ganz dasselbe wie Java: Instanzierung einer Enumeration durch Reflexion

Ich habe eine Map<Enum<?>, FooHandler> , die ich verwenden möchte, um Enum s zuzuordnen (egal, welcher Typ oder auch wenn sie vom selben Typ sind, solange sie Enum-Konstanten sind) für meine FooHandler -Klasse.

Ich möchte diese Karte mit einer Textdatei füllen, die ich gelesen habe. Ich kann es zur Arbeit bringen, aber ich habe zwei Warnungen, mit denen ich gerne umgehen würde:

%Vor%

Warnung # 1: ungeprüfter Cast Warnung # 2: Enum ist ein Rohtyp.

Ich bekomme # 1 und könnte mir einfach eine Warnung geben, aber ich kann die Warnung # 2 nicht schlagen; Ich habe Enum<?> ausprobiert, und das gibt mir nur einen Fehler über generische Art Capture gebundene Diskrepanz.

Alternative Implementierungen, die schlechter sind: Vor meinem <E extends Enum<E>> generischen Rückgabewert habe ich versucht, Enum zurückzugeben und es hat nicht funktioniert; Ich habe diese Warnungen / Fehler:

%Vor%
  1. Warnungen:

    %Vor%
  2. Fehler:

    %Vor%

und das:

%Vor%
  1. Warnung: Type safety: Unchecked cast from Class<capture#3-of ?> to Class<Enum<?>>
  2. Fehler: Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is not applicable for the arguments (Class<Enum<?>>, String). The inferred type Enum<?> is not a valid substitute for the bounded parameter <T extends Enum<T>>
Jason S 20.01.2011, 18:25
quelle

2 Antworten

6

Für # 1 gibt es keine Lösung außer SuppressWarnings("unchecked") .

Für # 2 gibt es ein Problem mit der Deklaration:

%Vor%

Sie können E zurückgeben, aber der Compiler kann E nicht ermitteln. Es gibt kein Argument vom Typ E oder Class<E> oder was auch immer, was es erlauben würde. Du kannst es schreiben, aber es wird irgendwo eine unkontrollierte Besetzung geben und wenn du es anrufst, kannst du ClassCastException bekommen. Also tu es nicht.

Ändere es einfach in

%Vor%

da dies funktioniert und fairer ist. Sie erhalten eine Warnung auf jeder Call-Site und das ist richtig, da es etwas zu warnen gibt.

    
maaartinus 20.01.2011, 18:54
quelle
5

Die Unterschrift

%Vor%

tut dir hier nicht gut.

Der <E extends Enum<E>> ermöglicht dem Aufrufer der Methode, das Ergebnis von getEnum einem beliebigen enum -Typ ohne Casting zuzuordnen:

%Vor%

Das macht jedoch keinen Sinn ... wenn der Aufrufer wüsste, welchen spezifischen Typ von enum die Methode zurückgeben würde, könnten sie etwas Sinnvolleres tun als SomeEnum.valueOf("SOMETHING") .

Das einzige, was hier Sinn macht, ist, dass getEnum nur Enum<?> zurückgibt, was wie das aussieht, was du wirklich willst:

%Vor%

Das obige kompiliert ohne Warnungen und funktioniert ordnungsgemäß. Die Umwandlung in Class<Enum> warning wird unterdrückt, weil wir wissen, dass dies nicht sicher ist und dass Enum.valueOf explodieren wird, wenn die Klasse mit dem angegebenen Namen keine enum -Klasse ist und das ist es, was wir wollen mach das.

    
ColinD 20.01.2011 18:57
quelle

Tags und Links