2009-09-15 39 views
7

Podría estar equivocado, pero supongo que de Why can't enums be declared locally in a method? que, dado que una enumeración en Java no puede declararse localmente, entonces, por lo tanto, es problemático que un método devuelva el tipo Enum? Puedo declarar que un método debe devolver un Enum (ver a continuación), pero ¿cómo se implementaría entonces un método para devolver algo que no sea nulo, o una referencia a un Enum declarado fuera del método? Mi primera inclinación sería investigar el uso de Generics para esto, pero me gustaría evitar cualquier desavenencia si la comunidad de SO me puede ayudar a evitarlos.¿Pueden los métodos de Java devolver el tipo Enum?

private Enum resources() { 
    return null; 
} 
+0

¿Desea devolver un tipo 'Enum', o un valor' Enum'? – jjnguy

+0

No estoy seguro de que el título de la pregunta sea el más apropiado. ¿Qué es lo que realmente quieres hacer? –

+0

Perdón por la confusión, y ciertamente podría estar equivocado en lo que estoy tratando de lograr (mi pensamiento empieza a salir mal a última hora de la tarde) pero pensé que me gustaría tener un método para devolver un Enum genérico * no * un miembro de un Enum. –

Respuesta

8

Creo que tiene razón, solo va a poder devolver null o Enum declarados en otro lugar. Pero no necesariamente tiene que especificar esa "otra cosa" en el momento de la compilación.

class EnumEnumerator<T extends Enum<T>> implements Iterable<T> { 
    private final Class<T> enumClass; 

    public EnumEnumerator(Class<T> enumClass) { 
     this.enumClass = enumClass; 
    } 

    public Iterator<T> iterator() { 
     T[] values = enumClass.getEnumConstants(); 
     return Arrays.asList(values).iterator(); 
    } 
    } 

Más tarde, se invoca mediante la especialización del constructor genérico y que pasa en la clase de enumeración que le interesa:

class EnumEnumeratorDemo { 
    enum Foo { 
     BAR, BAZ, QUX; 
     @Override public String toString() { 
      return name().toLowerCase(); 
     } 
    } 

    public static void main(String[] args) { 
     for (Foo f : new EnumEnumerator<Foo>(Foo.class)) { 
      System.out.println(f); 
     } 
    } 
} 

(Obviamente, esto es un ejemplo artificial y en la vida real que sólo debe llame a Foo.values ​​(), pero obtendrá la idea.)

+0

¿podrías agregar cómo se usa esta clase? – msysmilu

+0

hecho, espero que ayude. –

+1

p.s. para obtener la matriz de valores, puede hacer 'values ​​= enumClass.getEnumConstants()' – newacct

2

¿Qué estás tratando de lograr? Esta es una manera de devolver un Enum:

public class Test 
{ 
    public static void main(String args[]) 
    { 
     System.out.println(doit()); 
    } 

    public enum Foo { 
     BAR, 
     BAZ; 
    } 
    public static Enum doit() { 
     return Enum.valueOf(Foo.class,"BAR"); 
    } 
} 

Pero, supongo que esto no es lo que se va a?

+1

Quieres 'Enum '. –

+0

En realidad, no quiero nada de este código; parece algo raro de hacer :) – davetron5000

1

Sí, definitivamente es posible.

private Enum getRetentionPolicy() { 
    return java.lang.annotation.RetentionPolicy.SOURCE; 
} 

Si su pregunta es acerca de declarar enumeraciones, es posible que declara que:

  • en su propio archivo de java, similar a un alto nivel class;
  • dentro de un archivo java perteneciente a otra clase, similar a un interior estático class;
1

No del todo seguro de lo que su objetivo es, pero si quería volver un método generified (es decir, uno que sería anulado) que podría tener algo como lo siguiente:

public class MyEnumClass<T extends Enum<T>> { 
    public T resources() { 
     //do stuff here 
    } 
} 

No del todo seguro de lo usted ganaría allí, aunque puede ser beneficioso si habla de diferentes conjuntos de Enumeraciones y sus elementos.

Si está hablando de la clase Enum (es decir, el percursor del iterador) hasta donde yo sé, no se ha generado, por lo que no estoy seguro de que los genéricos ayuden mucho aquí.

1

Puede hacer referencia al valor de una enumeración por su nombre, p. Suit.SPADES.

Puede recorrer todos los valores utilizando el método values ​​() y elegir uno de los valores.

3

Todas las enumeraciones implementan la interfaz Enum, por lo que ciertamente puede escribir un método que devuelva una enumeración de esta manera. Pero este método devolverá un único valor enum. No hay forma de devolver un valor genérico que abarque toda la enumeración (aparte de devolver la clase y hacer la reflexión). Sin embargo, puede devolver todos los valores enum, que es más o menos lo que quiere, creo.

enum Resources { ONE, TWO, THREE } 
private Enum<?>[] resources() { 
    return Resources.values(); 
} 

Una ventaja de este enfoque es que se puede volver más o menos valores, por ejemplo:

enum Resources { ONE, TWO, THREE } 
enum MoreResources { UN, DEUX, TROIS } 
private Enum<?>[] resources() { 
    List<Enum<?>> resources = new ArrayList<Enum<?>>(); 
    resources.addAll(Arrays.asList(Resources.values()); 
    resources.addAll(Arrays.asList(MoreResources.values()); 
    return resources.toList(new Enum<?>[] {}); 
} 

Una mejor enfoque que es más typesafe es tener las enumeraciones de interés implementar una interfaz común p.ej

Puede agregar métodos adicionales a la interfaz para proporcionar más funciones.

3

Todo el punto de la forma en que Java hace Enums es que son seguros, por lo que no devolvería un Enum (que sería doblemente bueno) sino que devolverá el tipo real que defina (como "Suit")) que actúa como una clase. Suit tiene 4 instancias "Enumeradas".

Si esperaba un "Traje", ¿de qué serviría devolver un "Rango" de 7? ¡Rompería todo!

Además, si pasó un "Enum" o algún valor genérico, no podría llamar a métodos en él. Lo mejor de TypeSafe Enums es que puedes obtener un "Suit" y llamar a "Suit.getColor()" y esperar obtener el color de ese palo. También podría tener un ranksHigherThan (Traje s) que pueden cumplir:

assertTrue(SPADES.ranksHigherThan(HEARTS)); 

O, más importante aún:

suit1.ranksHigherThan(suit2); 

(suponiendo que ambos fueron pasados ​​y que no saben lo que son)

La seguridad de tipo es realmente sorprendente (aunque al principio se sienta un poco incómodo), abrázalo.

Cuestiones relacionadas