79

I've started to really like using C# and Java enums in my code for several reasons:

  • They are much more type-safe than integers, strings, or sets of boolean flags.
  • They lead to more readable code.
  • It's more difficult to set an enum to an invalid value than an int or string.
  • They make it easy to discover the allowed values for a variable or parameter.
  • Everything I've read indicates that they perform just as well as integers in C# and most JVMs.

However, the Android framework has numerous cases where flags of various types need to be passed around, but none of them seem to use enums. A couple of examples where I would think their use would be beneficial are Toast.LENGTH_SHORT / Toast.LENGTH_LONG and View.GONE, View.VISIBLE, etc.

Why is this? Do enums perform worse than simple integer values in Dalvik? Is there some other drawback I'm not aware of?

We Are All Monica
  • 13,000
  • 8
  • 46
  • 72

3 Answers3

66

This answer is out of date as of March 2011.

Enums can be used on Froyo and up - according to this answer (Why was “Avoid Enums Where You Only Need Ints” removed from Android's performance tips?) from a member of the Android VM team (and his blog).


Previous Answer:

The official Android team recommendation is to avoid enums whenever you can avoid it:

Enums are very convenient, but unfortunately can be painful when size and speed matter. For example, this:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

adds 740 bytes to your .dex file compared to the equivalent class with three public static final ints. On first use, the class initializer invokes the method on objects representing each of the enumerated values. Each object gets its own static field, and the full set is stored in an array (a static field called "$VALUES"). That's a lot of code and data, just for three integers. Additionally, this:

Shrubbery shrub = Shrubbery.GROUND;

causes a static field lookup. If "GROUND" were a static final int, the compiler would treat it as a known constant and inline it.

Source: Avoid Enums Where You Only Need Ints

Community
  • 1
  • 1
Sebastian Paaske Tørholm
  • 49,493
  • 11
  • 100
  • 118
  • 4
    So while C# enums *do* perform very well, Java enums do not since they are more complicated. Therefore my last bullet point isn't really true. Correct? – We Are All Monica Jan 27 '11 at 23:08
  • 25
    This is probably not valid anymore, see http://stackoverflow.com/questions/5143256/why-was-avoid-enums-where-you-only-need-ints-removed-from-androids-performance – Viktor Dahl Mar 19 '11 at 16:45
  • 2
    The Android documentation still advises not to use enum: **"Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android."** http://developer.android.com/training/articles/memory.html#Overhead – ThomasW Jul 01 '15 at 05:28
  • 1
    @SebastianPaaskeTørholm The link you've provided (this: http://developer.android.com/guide/practices/design/performance.html#avoid_enums ) doesn't show the tip anymore . – android developer Sep 09 '15 at 14:32
15

Integers are smaller, and require less overhead, something that still matters on mobile devices.

Russell Steen
  • 6,494
  • 6
  • 38
  • 56
  • In addition now we have good tool for Android Studio and Lint. I mean annotations `IntDef` and `StringDef`, which allow to declare some kind of *typedef*, so the usage of int constants is very convenient. http://blog.shamanland.com/2016/02/int-string-enum.html – Oleksii K. Feb 07 '16 at 14:27
  • yeah, but what about Retrofit models?(and for other network libraries I presume) How would you define a status response (e.g. succeeded, failed, token_expired) to map directly to POJO? – mitsest Sep 13 '17 at 09:54
5

A colleague of mine performed a small test regarding this situation. He auto generated a class and an enum with the same amount of "enums". I believe he generated 30000 entries.

The results were:

  • .class for the class was roughly 1200KB
  • .class for the enum was roughly 800KB

Hope this helps someone.

prolink007
  • 33,872
  • 24
  • 117
  • 185
  • I don't think that's the valid test. Having 30000 enums/static fields in a single place is not a realistic scenario. You'd need to compare a size of a big number of small classes/enums e.g. 1000 classes/enums 30 properties each. I bet that the total size will be quite different. – Iwo Banas Sep 11 '12 at 16:04
  • 7
    @Iwo Banas Any test is a valid test. Didn't say it would answer the question. Just offered it as extra information for anyone that might be interested. And the down vote seems very deserved, so thank you. -_- – prolink007 Sep 11 '12 at 16:22
  • Doesn't it show the opposite? That enum uses less ? And is it memory or storage that's 1200KB or 800KB ? – android developer Sep 09 '15 at 14:34