2015-01-11 3 views
5

Ich möchte eine generische Methode schreiben, die einen beschränkten Parameter verwendet, der Enum erweitert. Zum Beispiel, wenn ich eine Enum habe wie folgt:Generische Methode mit Bounded erweitert Enum-Parameter - kann nicht auf values ​​() zugreifen

public enum InputFlags{ 
    ONE (0000001), 
    TWO (0000002), 
    THREE (00000004); 

    public final int value; 

    InputFlags(int value){ 
     this.value = value; 
    } 
} 

kann ich dann wie folgt vor:

for (InputFlags ifg : InputFlags.values()){ 
      // Do something with ifg 
} 

Allerdings, wenn ich versuche, die oben in einer generischen Methode, deren Rückgabeparameter begrenzt ist, zu tun, ich kann nicht auf die values() Methode:

public static <T extends Enum> T getFlags(int f){ 
     T.values(); // NOT allowed, even though I have bounded by extending Enum. 
} 

Es scheint, als ob ich nicht values() in der generischen Methode zugreifen kann. Ist das eine Besonderheit von Enums oder gibt es einen Weg dahin?

+0

Scheint, wie Sie neu zu erfinden [ 'EnumSet'] (http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html). – Holger

Antwort

0

Dies ist eine Eigenheit von static Methoden. Es gibt in Java keine Möglichkeit, mit Generika oder anderweitig eine Schnittstelle zu definieren, die für static Methoden gilt, d. dass eine Klasse eine static Methode implementieren sollte/muss.

Darüber hinaus können Sie mit type (unter anderem) verhindern, dass Sie eine Typvariable T als Typnamen in einem Methodenaufruf-Ausdruck static verwenden.

+0

Wenn ich das 'static' Schlüsselwort nehme, bekomme ich immer noch das gleiche Problem. – Kerry

+0

@kerry 'values' ist die' statische' Methode, nicht Ihre 'getFlags'. –

+0

OK Ich habe Sie über das Schlüsselwort 'static' missverstanden. Ich muss über deine Antworten nachdenken, da ich das nicht in meinem eigenen Kopf ausarbeiten kann.In meiner (einfachen) Ansicht, da ich den Parameter in der generischen Methode auf enum beschränkt hatte, sollten dann sicher alle Enum-Methoden, statisch oder nicht-statisch verfügbar sein. – Kerry

1

values() ist eine statische Methode, die vom Compiler in die Klasse InputFlags eingefügt wird. Daher ist es nicht möglich, T.values() zu verwenden, insbesondere da T ein generischer Typ ist. Wenn Sie jedoch das Objekt Class von T erhalten können (normalerweise über getClass() oder indem Sie es an getFlags(int f, Class<T> clazz) übergeben), können Sie Class#getEnumConstants() für dieses Objekt verwenden.

+0

Ich kann immer noch nicht verstehen, warum es nicht verfügbar wäre, da ich den Parameter auf "Enum" beschränkt habe. Ich denke, ich muss dies eine Weile nachdenken. – Kerry

+0

values ​​() ist eine statische Methode in jeder Unterklasse von Enum, aber keine Methode in Enum selbst. Daher kann der Compiler die Methode nicht als Mitglied von Enum finden. Außerdem wird die Position einer statischen Methode (dh die Klasse, zu der sie gehört) zur Kompilierzeit aufgelöst, was hier nicht möglich ist. – Clashsoft

8

values() ist eine sehr seltsame Sache in Java. Schau in die Dokumentation für Enum - values() ist nicht mal da! values() ist überhaupt keine Methode von Enum. Stattdessen wird implizit eine static-Methode mit dem Namen values() zu jeder Klasse hinzugefügt, die Enum erweitert. Aber die values() Methode für eine enum unterscheidet sich von der values() Methode in einem anderen enum.

Die Tatsache, dass T extends Enum bedeutet, dass wenn tT hat geben Sie Instanz Methoden von Enum auf t aufrufen können. Sie können static Methoden der Enum nicht nennen (und selbst wenn Sie könnten, values() existiert nicht sowieso!)

values() nur dann sinnvoll ist, wenn Sie die tatsächliche enum mit Namen kennen. Es kann nicht verwendet werden, wenn Sie nur einen Typparameter T haben.

Der Weg um dieses Problem besteht darin, ein Class Objekt zu übergeben. Wie folgt aus:

public static <T extends Enum<T>> T getFlags(Class<T> clazz, int f){ 
    T[] array = clazz.getEnumConstants(); // This is how you can get an array. 
    Set<T> set = EnumSet.allOf(clazz);  // This is how you can get a Set.  
} 
Verwandte Themen