Dlaczego Android nie używa więcej wyliczeń?


79

Zacząłem bardzo lubić używanie wyliczeń C # i Java w moim kodzie z kilku powodów:

  • Są znacznie bardziej bezpieczne dla typów niż liczby całkowite, łańcuchy lub zestawy flag logicznych.
  • Prowadzą do bardziej czytelnego kodu.
  • Trudniej jest ustawić wyliczenie na nieprawidłową wartość niż wartość typu int lub string.
  • Ułatwiają odkrywanie dozwolonych wartości zmiennej lub parametru.
  • Wszystko, co przeczytałem, wskazuje, że działają one równie dobrze jak liczby całkowite w C # i większości maszyn JVM.

Jednak struktura systemu Android ma wiele przypadków, w których flagi różnych typów muszą być przekazywane, ale żaden z nich nie wydaje się używać wyliczeń. Kilka przykładów gdzie myślę, że ich stosowanie byłoby korzystne są Toast.LENGTH_SHORT/ Toast.LENGTH_LONGa View.GONE, View.VISIBLEitp

Dlaczego to? Czy wyliczenia działają gorzej niż proste wartości całkowite w Dalvik? Czy jest jakaś inna wada, której nie jestem świadomy?


10
Teraz możesz użyć enum. Zobacz stackoverflow.com/questions/5143256/…
— Thierry-Dimitri Roy

1
Świetny! Lubię enumy i jeszcze nie zabrałem się za ich wyjęcie.
— Wszyscy jesteśmy Monica

Odpowiedzi:


66

Ta odpowiedź jest nieaktualna w marcu 2011 r.

Wyliczenia mogą być używane we Froyo i nowszych wersjach - zgodnie z tą odpowiedzią ( dlaczego „Unikaj wyliczeń tam, gdzie potrzebujesz tylko Ints” usunięto ze wskazówek dotyczących wydajności Androida? ) Od członka zespołu Android VM (i jego bloga ).


Poprzednia odpowiedź:

Oficjalnym zaleceniem zespołu ds. Androida jest unikanie wyliczeń, ilekroć możesz tego uniknąć:

Wyliczenia są bardzo wygodne, ale niestety mogą być bolesne, gdy liczą się rozmiar i szybkość. Na przykład to:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

dodaje 740 bajtów do pliku .dex w porównaniu z równoważną klasą z trzema publicznymi statycznymi końcowymi wartościami int. Przy pierwszym użyciu inicjator klasy wywołuje metodę na obiektach reprezentujących każdą z wyliczonych wartości. Każdy obiekt otrzymuje własne pole statyczne, a pełny zestaw jest przechowywany w tablicy (statycznym polu o nazwie „$ VALUES”). To dużo kodu i danych, tylko dla trzech liczb całkowitych. Dodatkowo to:

Shrubbery shrub = Shrubbery.GROUND;

powoduje statyczne wyszukiwanie pól. Gdyby „GROUND” było statyczną wartością końcową int, kompilator potraktowałby ją jako znaną stałą i wstawiłaby do niej.

Źródło: Unikaj wyliczeń tam, gdzie potrzebujesz tylko Ints


4
Więc podczas gdy C # teksty stałe należy wykonać bardzo dobrze, teksty stałe Java nie robić, ponieważ są one bardziej skomplikowane. Dlatego mój ostatni punkt nie jest prawdziwy. Poprawny?
— Wszyscy jesteśmy Monica

25
To prawdopodobnie już nie jest poprawne, patrz stackoverflow.com/questions/5143256/ ...
— Viktor Dahl

2
Dokumentacja systemu Android nadal odradza używanie wyliczeń: „Wyliczenia często wymagają więcej niż dwa razy więcej pamięci niż stałe statyczne. Należy bezwzględnie unikać używania wyliczeń w systemie Android”. developer.android.com/training/articles/memory.html#Overhead
— ThomasW

1
@ SebastianPaaskeTørholm Podany przez Ciebie link (to: developer.android.com/guide/practices/design/… ) nie wyświetla już wskazówki.
— programista Androida

14

Liczby całkowite są mniejsze i wymagają mniejszych nakładów, co nadal ma znaczenie na urządzeniach mobilnych.


Ponadto mamy teraz dobre narzędzie dla Android Studio i Lint. Mam na myśli adnotacje IntDefi StringDef, które pozwalają na zadeklarowanie jakiegoś typu typedef , więc użycie stałych int jest bardzo wygodne. blog.shamanland.com/2016/02/int-string-enum.html
— Oleksii K.

tak, ale co z modelami Retrofit? (i przypuszczam, że dla innych bibliotek sieciowych) Jak zdefiniowałbyś odpowiedź statusu (np. powodzenie, niepowodzenie, token_expired), aby mapować bezpośrednio do POJO?
— mitsest

5

Mój kolega wykonał mały test dotyczący tej sytuacji. Automatycznie wygenerował a classi enumz taką samą ilością „wyliczeń”. Myślę, że wygenerował 30000 wpisów.

Wyniki były następujące:

  • .classza classokoło 1200 KB
  • .classza enumokoło 800 KB

Mam nadzieję, że to komuś pomoże.


Nie sądzę, żeby to był ważny test. Posiadanie 30000 wyliczeń / pól statycznych w jednym miejscu nie jest realistycznym scenariuszem. Będziesz musiał porównać wielkość dużej liczby małych klas / wyliczeń, np. 1000 klas / wyliczeń po 30 właściwości każda. Obstawiam, że całkowity rozmiar będzie zupełnie inny.
— Iwo Banas,

7
@Iwo Banas Każdy test jest ważnym testem. Nie powiedziałem, że to odpowie na pytanie. Po prostu zaproponowałem to jako dodatkowe informacje dla każdego, kto może być zainteresowany. A głos negatywny wydaje się bardzo zasłużony, więc dziękuję. -_-
— prolink007

Czy to nie pokazuje czegoś przeciwnego? Że enum zużywa mniej? Czy jest to pamięć lub pamięć masowa o pojemności 1200 KB czy 800 KB?
— programista Androida
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.