Warum verwendet Android nicht mehr Aufzählungen?

79

Ich habe aus mehreren Gründen angefangen, C # - und Java-Enums in meinem Code zu verwenden:

  • Sie sind viel typsicherer als Ganzzahlen, Zeichenfolgen oder Sätze von Booleschen Flags.
  • Sie führen zu besser lesbarem Code.
  • Es ist schwieriger, eine Aufzählung auf einen ungültigen Wert zu setzen als ein int oder eine Zeichenfolge.
  • Sie erleichtern das Ermitteln der zulässigen Werte für eine Variable oder einen Parameter.
  • Alles, was ich gelesen habe, zeigt an, dass sie in C # und den meisten JVMs genauso gut funktionieren wie ganze Zahlen.

Das Android-Framework hat jedoch zahlreiche Fälle, in denen Flags verschiedener Typen weitergegeben werden müssen, aber keiner von ihnen scheint Aufzählungen zu verwenden. Ein paar Beispiele , wo ich ihre Verwendung wäre denken würde vorteilhaft sind Toast.LENGTH_SHORT/ Toast.LENGTH_LONGund View.GONE, View.VISIBLEusw.

Warum ist das? Sind Aufzählungen in Dalvik schlechter als einfache ganzzahlige Werte? Gibt es einen anderen Nachteil, den ich nicht kenne?

Wir sind alle Monica
quelle
10
Es ist in Ordnung, jetzt enum zu verwenden. Siehe stackoverflow.com/questions/5143256/…
Thierry-Dimitri Roy
1
Toll! Ich mag Aufzählungen und war noch nicht dazu gekommen, sie herauszunehmen.
Wir sind alle Monica

Antworten:

66

Diese Antwort ist seit März 2011 veraltet.

Enums können auf Froyo und höher verwendet werden - gemäß dieser Antwort ( Warum wurde "Vermeiden Sie Enums, bei denen Sie nur Ints benötigen" aus den Leistungstipps von Android entfernt? ) Von einem Mitglied des Android VM-Teams (und seinem Blog ).


Vorherige Antwort:

Die offizielle Empfehlung des Android-Teams lautet, Aufzählungen zu vermeiden, wann immer Sie dies vermeiden können:

Aufzählungen sind sehr praktisch, können aber leider schmerzhaft sein, wenn Größe und Geschwindigkeit eine Rolle spielen. Zum Beispiel:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

Fügt Ihrer .dex-Datei 740 Bytes hinzu, verglichen mit der entsprechenden Klasse mit drei öffentlichen statischen endgültigen Ints. Bei der ersten Verwendung ruft der Klasseninitialisierer die Methode für Objekte auf, die jeden der aufgezählten Werte darstellen. Jedes Objekt erhält ein eigenes statisches Feld, und der gesamte Satz wird in einem Array gespeichert (ein statisches Feld namens "$ VALUES"). Das ist viel Code und Daten, nur für drei ganze Zahlen. Zusätzlich ist dies:

Shrubbery shrub = Shrubbery.GROUND;

verursacht eine statische Feldsuche. Wenn "GROUND" ein statisches endgültiges int wäre, würde der Compiler es als bekannte Konstante behandeln und es inline setzen.

Quelle: Vermeiden Sie Aufzählungen, bei denen Sie nur Ints benötigen

Sebastian Paaske Tørholm
quelle
4
Während also die C # Aufzählungen haben eine sehr gute Leistung, Java Aufzählungen nicht , da sie mehr kompliziert sind. Daher ist mein letzter Punkt nicht wirklich wahr. Richtig?
Wir sind alle Monica
Es scheint so, ja.
Sebastian Paaske Tørholm
25
Dies ist wahrscheinlich nicht mehr gültig, siehe stackoverflow.com/questions/5143256/…
Viktor Dahl
2
In der Android-Dokumentation wird weiterhin davon abgeraten, Enum zu verwenden: "Enums benötigen häufig mehr als doppelt so viel Speicher wie statische Konstanten. Sie sollten die Verwendung von Enums unter Android strikt vermeiden." developer.android.com/training/articles/memory.html#Overhead
ThomasW
1
@ SebastianPaaskeTørholm Der von Ihnen bereitgestellte Link (this: developer.android.com/guide/practices/design/… ) zeigt den Tipp nicht mehr an.
Android-Entwickler
14

Ganzzahlen sind kleiner und erfordern weniger Overhead, was auf Mobilgeräten immer noch wichtig ist.

Russell Steen
quelle
Außerdem haben wir jetzt ein gutes Tool für Android Studio und Lint. Ich meine Anmerkungen IntDefund StringDef, die es erlauben, eine Art typedef zu deklarieren , daher ist die Verwendung von int-Konstanten sehr praktisch. blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.
Ja, aber was ist mit Retrofit-Modellen? (und für andere Netzwerkbibliotheken, nehme ich an) Wie würden Sie eine Statusantwort definieren (z. B. erfolgreich, fehlgeschlagen, token_expired), um sie direkt POJO zuzuordnen?
Mitsest
5

Ein Kollege von mir führte einen kleinen Test zu dieser Situation durch. Er hat automatisch ein classund ein enummit der gleichen Anzahl von "Aufzählungen" generiert. Ich glaube, er hat 30000 Einträge generiert.

Die Ergebnisse waren:

  • .classdenn das classwar ungefähr 1200KB
  • .classdenn das enumwar ungefähr 800KB

Hoffe das hilft jemandem.

prolink007
quelle
Ich denke nicht, dass das der gültige Test ist. 30000 Aufzählungen / statische Felder an einem Ort zu haben, ist kein realistisches Szenario. Sie müssten eine Größe einer großen Anzahl kleiner Klassen / Aufzählungen vergleichen, z. B. 1000 Klassen / Aufzählungen mit jeweils 30 Eigenschaften. Ich wette, dass die Gesamtgröße ganz anders sein wird.
Iwo Banas
7
@Iwo Banas Jeder Test ist ein gültiger Test. Ich habe nicht gesagt, dass es die Frage beantworten würde. Ich habe es nur als zusätzliche Information für alle angeboten, die interessiert sein könnten. Und die Abwahl scheint sehr verdient zu sein, also danke. -_-
prolink007
Zeigt es nicht das Gegenteil? Diese Aufzählung verbraucht weniger? Und ist es Speicher oder Speicher, der 1200 KB oder 800 KB groß ist?
Android-Entwickler