¿Por qué Android no usa más enumeraciones?

79

Me ha empezado a gustar mucho el uso de enumeraciones de C # y Java en mi código por varias razones:

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

Sin embargo, el marco de Android tiene numerosos casos en los que es necesario pasar indicadores de varios tipos, pero ninguno de ellos parece usar enumeraciones. Un par de ejemplos en los que yo creo que su uso sería beneficioso son Toast.LENGTH_SHORT/ Toast.LENGTH_LONGe View.GONE, View.VISIBLE, etc.

¿Por qué es esto? ¿Las enumeraciones funcionan peor que los valores enteros simples en Dalvik? ¿Hay algún otro inconveniente del que no tenga conocimiento?

Todos somos monica
fuente
10
Está bien usar enum ahora. Ver stackoverflow.com/questions/5143256/…
Thierry-Dimitri Roy
1
¡Excelente! Me gustan las enumeraciones y todavía no había llegado a sacarlas.
Todos somos Monica

Respuestas:

66

Esta respuesta está desactualizada en marzo de 2011.

Las enumeraciones se pueden usar en Froyo y versiones posteriores, de acuerdo con esta respuesta ( ¿Por qué se eliminó "Evitar enumeraciones donde solo necesita Ints" de los consejos de rendimiento de Android? ) De un miembro del equipo de VM de Android (y su blog ).


Respuesta anterior:

La recomendación oficial del equipo de Android es evitar las enumeraciones siempre que pueda evitarlo:

Las enumeraciones son muy convenientes, pero desafortunadamente pueden ser dolorosas cuando el tamaño y la velocidad son importantes. Por ejemplo, esto:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

agrega 740 bytes a su archivo .dex en comparación con la clase equivalente con tres entradas finales estáticas públicas. En el primer uso, el inicializador de clase invoca el método en objetos que representan cada uno de los valores enumerados. Cada objeto tiene su propio campo estático y el conjunto completo se almacena en una matriz (un campo estático llamado "$ VALUES"). Eso es mucho código y datos, solo para tres enteros. Además, esto:

Shrubbery shrub = Shrubbery.GROUND;

provoca una búsqueda de campo estático. Si "GROUND" fuera un int final estático, el compilador lo trataría como una constante conocida y lo integraría.

Fuente: Evite las enumeraciones donde solo necesita Ints

Sebastian Paaske Tørholm
fuente
4
Así, mientras que C # enumeraciones no funcionan muy bien, las enumeraciones de Java no lo hacen, ya que son más complicadas. Por lo tanto, mi última viñeta no es realmente cierta. ¿Correcto?
We Are All Monica
25
Probablemente esto ya no sea válido, consulte stackoverflow.com/questions/5143256/…
Viktor Dahl
2
La documentación de Android todavía aconseja no usar enumeraciones: "Las enumeraciones a menudo requieren más del doble de memoria que las constantes estáticas. Debes evitar estrictamente el uso de enumeraciones en Android". developer.android.com/training/articles/memory.html#Overhead
ThomasW
1
@ SebastianPaaskeTørholm El enlace que ha proporcionado (esto: developer.android.com/guide/practices/design/… ) ya no muestra la sugerencia.
desarrollador de Android
14

Los números enteros son más pequeños y requieren menos gastos generales, algo que aún importa en los dispositivos móviles.

Russell Steen
fuente
Además ahora tenemos una buena herramienta para Android Studio y Lint. Me refiero a anotaciones IntDefy StringDef, que permiten declarar algún tipo de typedef , por lo que el uso de constantes int es muy conveniente. blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.
sí, pero ¿qué pasa con los modelos Retrofit? (y para otras bibliotecas de red, supongo) ¿Cómo definiría una respuesta de estado (por ejemplo, exitosa, fallida, token_expired) para mapear directamente a POJO?
mitsest
5

Un colega mío realizó una pequeña prueba sobre esta situación. Él generó automáticamente una classy unaenum con la misma cantidad de "enumeraciones". Creo que generó 30000 entradas.

Los resultados fueron:

  • .classpara el classera aproximadamente 1200KB
  • .classpara el enumera aproximadamente 800KB

Espero que esto ayude a alguien.

prolink007
fuente
No creo que esa sea la prueba válida. Tener 30000 enums / campos estáticos en un solo lugar no es un escenario realista. Necesitaría comparar un tamaño de un gran número de clases / enumeraciones pequeñas, por ejemplo, 1000 clases / enumeraciones 30 propiedades cada una. Apuesto a que el tamaño total será bastante diferente.
Iwo Banas
7
@Iwo Banas Cualquier prueba es una prueba válida. No dijo que respondería la pregunta. Simplemente lo ofrecí como información adicional para cualquiera que pudiera estar interesado. Y el voto en contra parece muy merecido, así que gracias. -_-
prolink007
¿No muestra lo contrario? ¿Esa enumeración usa menos? ¿Y es memoria o almacenamiento de 1200 KB o 800 KB?
desarrollador de Android