2011-03-09 12 views
30

¿Cuáles son las ventajas (o desventajas) de tener un enum versus tener un conjunto de static final int en aplicaciones de Android con Java? ¿Hay optimizaciones de eficiencia o rendimiento que ocurren que favorecen el uso de uno u otro?Android: enum vs static final ints?

te pido esto en el contexto de, por ejemplo requestCodes intención y tal - que tienden a ser enteros en el código de ejemplo Android, en contraposición a los valores de una enumeración, que yo estaba acostumbrado en C

+0

enumeraciones pueden ser nulos, enteros no puede – Erik

+13

Ver [¿Por qué no utiliza Android más enumeraciones?] (Http: //stackoverflow.com/questions/4822877/why-doesnt-android-use-more-enums) y [¿Por qué se eliminó de los consejos de rendimiento de Android "Avoid Enums Where You Only Need?"] (http://stackoverflow.com/questions/5143256/why-was-avoid-enums-where-you-only-need-ints-removed-from-androids-performance) y [Cómo funciona h memoria do Enums take?] (http://stackoverflow.com/questions/143285/how-much-memory-do-enums-take) –

+2

Escriba el código de la manera más clara posible; luego, si descubres que tienes un problema de rendimiento y descubres que no es IO, considera romper tu código por el bien del rendimiento – iluxa

Respuesta

27

ventajas de Enum this question:

  • que son mucho más seguros de tipo de números enteros, cadenas, o conjuntos de banderas booleanas.
  • Conducen a un código más legible.
  • Es más difícil establecer una enumeración en un valor no válido que una cadena int o .
  • Facilitan el descubrimiento de los valores permitidos para una variable o el parámetro .
  • Todo lo que he leído indica que funcionan tan bien como los enteros en C# y en la mayoría de las JVM.

yo añadiría:

  • enumeraciones pueden tener variables miembro y de instancia, mientras que un int no puede.

Como la mayoría de las abstracciones, en general son inequívocamente ventajosas una vez que su performance catches up. Especialmente en el código de su aplicación (a diferencia del código del framework) elegiría enumeraciones sobre otros métodos que las simulan.

+0

Gracias por el enlace re: android docs, lo leí hace un tiempo y siempre me pregunté sobre él. – Ozzy

12

Una respuesta muy simple a partir de las experiencias personales sería que los Enums ofrecen mucha mejor seguridad de tipo o, en otras palabras, el compilador juega un papel más activo para mantener el código libre de errores.

Por otro lado, como los Enums son "ciudadanos de segunda clase" del mundo de los objetos, pueden ser difíciles de usar en algunos de los patrones de diseño más sutiles que se usan hoy en día, especialmente cuando se trata de genéricos.

Y, por último, puede usar ints estáticos finales en un campo de bits. que no podía hacer lo siguiente con una enumeración:

int selectedOptions = Options.OPTION1 | Options.OPTION2 | Options.OPTION3; 
+0

Si bien acepté la primera respuesta como la respuesta correcta a la pregunta, creo que el último punto que sacas es muy bueno. Nunca lo intenté yo mismo, pero es un hecho muy bueno saberlo. ¡Gracias! – Cubic

+6

En esa última parte, usar EnumSet es el camino recomendado. Nunca me gustó mucho el patrón de banderas de bits. – Spektr

+0

La seguridad de tipo es un gran problema. Puede obtener todos los beneficios de seguridad de tipo de enumeraciones, al mismo tiempo que conserva la compatibilidad con el código existente, ejecutando un análisis estático como [Fake Enum Checker] (https://types.cs.washington.edu/checker-framework/ current/checker-framework-manual.html # fenum-checker). Si no te importa la compatibilidad con versiones anteriores con el código existente, usar una enumeración suele ser mejor. – mernst

3

Una de las ventajas de enteros sobre las enumeraciones se encuentra en una fábrica de clase. El siguiente código de C# no es extensible:

class Factory 
{ 
    public enum DrawableType {CIRCLE,SQUARE}; 
    public static Drawable GetInstance(DrawableEnum e) 
    { 
     if (e == DrawableType.CIRCLE) 
     { 
      return new Circle(); 
     } 
     else if (e == DrawableType.SQUARE) 
     { 
      return new Square(); 
     } 
     else 
     { 
      throw new IndexOutOfRangeException(); // should never get here 
     } 
    } 

Escribí este código deficiente. Al revisar Patrones de diseño, la pandilla de cuatro utilizó un int. Traté de recuperar here.

7

Bueno ... de acuerdo con a bald guy Los mensajes son really bad for memory.

Debe utilizar @IntDef/@StringDef anotaciones:

public static final int NAVIGATION_MODE_STANDARD = 0; 
public static final int NAVIGATION_MODE_LIST = 1; 
public static final int NAVIGATION_MODE_TABS = 2; 

@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) 
public @interface NavigationMode {} 

y luego

@NavigationMode 
public abstract int getNavigationMode(); 

public abstract void setNavigationMode(@NavigationMode int mode);