Google warns us against using enums in our Android code. A lot of developers don’t heed this warning. Each side has their favorite list of arguments that they like to trot out in defense of their position on the issue of whether to use enums. In this post, we’ll examine the main arguments on each side of this issue and we’ll contribute our own thoughts to the debate.

Disclaimer: The people on both sides of this debate are obviously extremely intelligent people, so what follows is not supposed to be insult to either side or to suggest that anyone is silly for taking a certain position on this issue. In fact, our position on this issue is very weakly held and we think that’s its very possible that there might be nuances to the debate that we miss here.

Why Google Doesn’t Like Enums

Let’s start by looking at Google’s reasons for warning us against enums. The first reason is found in the “Managing Your App’s Memory” developer doc:

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

Apparently, Google’s current stance on this is not as strong as suggested by this sentence because in the second chapter of the more recent Developing for Android medium article series we see a more nuanced position being taken:

An occasional enum is not a big deal in terms of the memory it consumes or its allocation costs. And Proguard can, in some situations where it can statically analyze all usages, optimize enums to int values. But enums become a problem when used widely across a large application or, even worse, when used broadly in a library or an API that is then used by many other applications.

Here the position seems to be more like, “Avoid enums, unless there are a couple of cases where it would be really useful to use one.”

In the previous chapter of Developing for Android Apps, we are told why memory is such a big deal when developing for Android:

It is also crucial to remember that Android runs multiple activities and services in parallel. This dynamic is critical to creating a good user experience as users switch between recent apps, because these apps don’t have to re-launch from scratch. But this means that if any of these apps consume more memory than they need to, then there will be less system memory left over for the others. When that happens, the system will evict app processes (shutting them down), forcing the user into a situation where apps are constantly re-launching when the user switches to them because they cannot stay present in the background due to memory pressure.

So overall: use as little memory as you can, because the entire system suffers if you don’t.

The basic point here seems to be: When we don’t use as little memory as possible, user experience suffers because it takes longer for the user to switch between Activities.

Earlier this year, Dianne Hackborn, an Android framework engineer created a G+ post that gave some additional reasons why enums are usually to be avoided. She gave these reasons in the context of her reaction to this article on the oft quoted phrase “Premature Optimization is the Root of All Evil.”

Hackborn’s general response to the article is well summed up in the following quotation:

…part of our job is to understand the actual trade-offs we are making during implementation. There are many things you can do that will be significantly more expensive than other options, which really aren’t worth whatever small advantages they provide…That is not “premature optimization,” that is making good use of your tools.”

Hackborn then goes on to discuss enums as a specific example of a Java language feature that provides little benefit while having a big memory cost:

…there are a lot of things in the Java language that can lead to significantly less efficient results than other equally viable approaches…Java enums are tremendously more expensive in code size than simple static final ints

Here, Hackborn’s position seems to be this: there are a lot of cases where enums don’t provide any real benefit while also taking up additional memory. In these cases, don’t use enums. Use static final ints instead.

Hackborn’s position here fits nicely with the advice given in the “Avoid Enums” section of the above quoted memory chapter in Developing for Android:

Note that using the @IntDef annotation, which is supported by Android Studio and Gradle 1.3+, will give your code build-time type safety (when lint errors are enabled), while retaining the size and performance benefits of using int variables.

Why Some Devs Still Use Enums Anyway

We can start to see why some developers resist Google’s advice if we look at some of the responses to Dianne Hackborn’s post.

The first relevant response comes from Matthias Kappler. He says, referring in general to the optimizations Hackborn discusses, that:

Having to spend time on optimizing unimportant things such as enums or loops cuts into our time to build value for the customer and limits our ability to write expressive and stable code…much of the performance advice given by Google really affects portions of the code base that typically do not matter…Google really needs to get a reality check about real world team sizes, capacity, and the limited time we have in cranking out customer value.

Here I interpret Kappler to be saying, “As application developers with limited resources, we’ve got bigger things to worry about than optimizing enums, especially since having enums in the code base doesn’t make an important difference to performance and they help us write more stable code.”

Jake Wharton, in a tweet referencing Kappler’s comment, expressed his strong agreement:

Who’s right?

Before we weigh in on the issue, we want to remind the reader that we aren’t trying to be in the business of insulting anyone on either side of the debate. Instead, we are only trying to think carefully and critically about the arguments presented above so that we can get a better idea of when, if it all, it makes sense to use enums.

We think that if Google’s position is merely that we shouldn’t use enums when an @IntDef will do the trick and that we should be cautious about spreading enums throughout our entire code base, that Google is probably on the right side of this debate.

Here’s why we think this:

Kappler’s point about having limited time to deliver value to the customer only makes sense if enums are actually making the code base easier to write, understand, and maintain. If Google is only suggesting that we refrain from using enums when there is no little or benefit to using enums, then there really isn’t a conflict between Kappler’s point and Google’s position.

(Its possible that Hackborn has already said this to Kappler. There’s a comment in the thread that’s directed towards Mathias Agopian, but Agopian doesn’t seem to have made any comments in that thread, so its possible that Hackborn addressed her response to the wrong “Matthias.” Its also possible that Hackborn addressed the right person but that Agopian deleted his comment on the thread after Hackborn responded.)

Kappler’s point about enums not affecting app performance, moreover, seems to ignore the point that using more memory than necessary makes it more likely that the system will have to kill Activities and this makes the Android experience appear slower to the user.

For these two reasons, we’re sympathetic with what we take to be Google’s position on this issue, but again, we’re open to being wrong about our views on this and we suspect that there are nuances to the debate that we’ve missed.

Feel free to tell us your thoughts on the issue on Twitter or Google Plus.

By the way, if you’re hiring Android developers or looking for an Android developer position, you should check out our main site page. We working on a tool that might be useful for you.