Enum-Klassen sind in der Android-Welt aus verschiedenen Gründen umstritten, werden aber dennoch von erfahrenen Entwicklern Tag für Tag verwendet. Warum ist das so?
(Achtung: Die Syntax des Codes hier ist zwar in Kotlin, aber alle Informationen hier gelten auch für Java-Enum-Klassen)
Was ist eine Enum-Klasse?
Einfach gesagt ist eine Enum ein spezieller Klassentyp, der eine Liste von Konstanten enthält. Am häufigsten wird dies verwendet, um verschiedene Typen eines bestimmten Objekts darzustellen, oder wenn eine Variable nur einen bestimmten Wert annehmen kann.
enum class Direction { NORTH, SOUTH, EAST, WEST}
Die Konstanten einer Enum-Klasse benötigen nicht unbedingt einen Wert. Ohne einen Wert können sie in der Validierung durch ifs und switch-Anweisungen verwendet werden.
val directionToTreasure = Direction.NORTHwhen(directionToTreasure) { Direction.NORTH -> indicateNorth() Direction.SOUTH -> indicateSouth() Direction.EAST -> indicateEast() Direction.WEST -> indicateWest()}
Wahrscheinlich nicht der beste Weg, um diese Funktionen anzuzeigen, aber Sie verstehen die Idee. Zumindest wird es viel Spaß machen
Ihre Verwendung kann jedoch erweitert werden, um Werte einzuschließen, die jeder Konstanten zugeordnet sind.
enum class Color(val rgb: Int) { RED(0xFF0000) GREEN(0x00FF00) BLUE(0x0000FF)}
Wenn Sie Enum-Klassen auf diese Weise verwenden, können Sie ihren Wert wie folgt erhalten:
val shirtColour = Color.BLUEval color: Int = shirtColour.rgb
Was kann eine Enum sonst noch tun?
Um es auf den Punkt zu bringen, verdammt viel
Erstens können Enums anstelle von Konstanten als anonyme Klassen mit eigenen Methoden und überschreibenden Basismethoden implementiert werden.
enum class ProtocolState yadayada {}
Sie können auch Schnittstellen in ähnlicher Weise implementieren
enum class IntArithmetics yadayada {}
Schließlich hat enum zwei Konstanten, die einige ziemlich nützliche Werte liefern.
val name: String // The name of the constantval ordinal: Int // The position of the constant in the list of valuesif (shirtColour.name == "BLUE") { // Do some blue stuff}
Dank der Verwendung dieser Konstanten kann man auch bequem zwischen enum und String/Int-Typen mappen.
Enum -> Int
yourEnum.ordinal
Int -> Enum
EnumType.values()
String -> Enum
EnumType.valueOf(yourString)
Enum -> String
yourEnum.name
Lobende Erwähnung für diesen Typen auf StackOverflow, der dieses Mapping geteilt hat
Was ist der Zweck von Enum-Klassen?
Ich verstehe Sie, es ist nicht ganz einfach, aber ich werde Sie aufklären.
Grundsätzlich werden Enum-Klassen verwendet, um lesbaren Code zu erzeugen. Wenn man ein Objekt hat, das mehrere verschiedene Typen haben kann, ist es viel prägnanter, sie mit einem lesbaren Wert zu identifizieren als mit einer beliebigen Ganzzahl.
// Bad codewhen(direction) { 0 -> goNorth() 1 -> goSouth() 2 -> goEast() 3 -> goWest()}// Good codewhen(direction) { Direction.NORTH -> goNorth() Direction.SOUTH -> goSouth() Direction.EAST -> goEast() Direction.WEST -> goWest()}
Ein weiterer nützlicher Zweck von Enums ist, wenn man Daten hat, die als String reinkommen, aber schließlich auf einen int-Wert gemappt werden müssen, z.B. wenn die API den Typ des Objekts angibt, man ihn aber an einen RecyclerView-Adapter weitergeben muss, der für View-Typen einen int-Wert benötigt. Ich persönlich habe diese Methode in meiner Enum-Klasse verwendet, um das zu erreichen.
@JvmStaticfun getType(type: String): BlockType? = when(type) { "hero" -> ContentHero "products" -> ContentProductList else -> null }
Warum Sie keine Enum-Klassen verwenden sollten
Ich wette, Sie denken jetzt „Moment mal. Du hast mir alles über die Verwendung von Enums erzählt und jetzt sagst du mir, dass ich sie nicht verwenden soll?“. Hör mir zu, Kumpel.
Einfach gesagt, Enums sind teuer, Kumpel! Ich weiß, dass Handys immer besser werden, aber erstens gibt es immer noch zu viele Leute mit weniger leistungsstarken Handys, und zweitens verbrauchen die Art und Weise, wie wir Anwendungen erstellen, und die Bibliotheken, die wir verwenden, auch mehr Speicher.
Das ist nichts Neues. Enums wären ein Speicherproblem für Telefone, die mit Dalvik laufen, aber das wurde im Grunde genommen durch die ART (Android Runtime Machine) abgelöst. Zusammen mit der Tatsache, dass selbst Menschen in ärmeren Ländern ziemlich leistungsfähige Telefone haben und dass Proguard den Code jetzt besser denn je optimieren kann, kann man mit Sicherheit sagen, dass Enums kein Leistungsproblem mehr darstellen.
Es gibt immer noch ein paar Alternativen, die man verwenden kann, um ähnliche Ergebnisse wie mit einer Enum-Klasse zu erzielen.
Konstanten
Konstanten sind auch super prägnant. Sie enthalten einen einzigen Wert und geben ihm einen Namen. Sie sind auch extrem leichtgewichtig.
*Def
Die *Def-Annotation ist auch großartig, wenn man eine Variable hat, die nur bestimmte Werte annimmt.
@IntDef({RED, GREEN, BLUE})
Warum sollte man sich trotzdem für Enums entscheiden?
Wo die Enums viel mehr glänzen als ihre funktionalen Geschwister, ist die Erschöpfung. In Kotlin kann man eine switch-Anweisung wie diese verwenden
val foo = when(someEnum) {}
Und wenn man das tut, ist man gezwungen, für jede Konstante in der Enum einen Fall zu behandeln, sonst lässt sich der Code nicht kompilieren. Bei Konstanten und *def-Annotationen erhalten Sie bestenfalls Lint-Warnungen. Enums führen einfach zu sichererem Code.
(Credits to u/-manabreak from Reddit for this)
Solange also die Verwendung von Enums zu prägnanterem Code für Ihre Anwendung führt und vor allem im Fall von Kotlin zu besserer Fallsicherheit, können Sie nach Herzenslust enumerieren.