16

I have a question that when should we use Enum and when should we use a final constants?

I know that it has been discussed at Enums and Constants. Which to use when? though it is C# question.

My question is why Android use so many Constants rather than Enum? For example , Context

In my opinion, if we use constants, there may be the risk that as below: if we define a LEVEL Constant that

 public static final int LEVEL_LOW=1;
 public static final int LEVEL_MEDIUM=2;
 public static final int LEVEL_HIGH=3;

when we pass a param of int =4. it will not have compile error, and if we pass a number of 1, the code reader may not easily know what it means.

But Enum can solve this problem though it may cause more overhead since it is Object.

So why Android uses constants instead of Enum? Is there any principle that when should we use constants or Enum in such case?

Community
  • 1
  • 1
JaskeyLam
  • 15,405
  • 21
  • 114
  • 149
  • 1
    You could use Enum when you want to make sure that you are passing a Subset of your *pre-defined* constants. – TheLostMind Jun 30 '14 at 13:25
  • 1
    I did wonder this myself too. I don't think the Android source code even uses enums at all. – wvdz Jun 30 '14 at 13:26
  • 2
    Use enums in your code. In Android many values are flags that can be added (OR'ed). Beside that Android core is "quite old" so it could be that they started development when enums were not part of Java. Beside that it's an embedded system, enums need more memory. – brummfondel Jun 30 '14 at 13:27
  • @popovitsj - quite right... All i ever see in android are public static final constants. – TheLostMind Jun 30 '14 at 13:28
  • As far as I know, Enum is introduced in java 5, which should be before the android is written. Isn't it? – JaskeyLam Jun 30 '14 at 13:31
  • 1
    @jaskey wikipedia says that Android started in 2003, Java 5 was introduced 2005. Beside that the core is C/C++ which works with numbers. – brummfondel Jun 30 '14 at 13:35
  • Enum usage is not recommended (in Android) as it is not memory efficient – Parth Kapoor Jun 30 '14 at 13:43
  • 3
    imho, use integers when you working with some low level api, or you have limited resources, and you need to fight for each free kb. otherwise, i think is better to use enums, they prevent your methods from accepting invalid data, and increase readability – user902383 Jun 30 '14 at 13:48

5 Answers5

16

This is related to android history. There were unconfirmed performance issues in versions before Froyo. It was recommended to not use enum by the developers. Since Froyo the Designing for Performance documentation was rewritten as described here.

As you may have noticed, we rewrote the Designing for Performance documentation for Froyo. Previously it was a bunch of stuff that may have been true at some point, but had long ceased to bear any relationship to reality. In Froyo, every single claim in the document is backed by a benchmark to prove (or, in future, disprove) it. You can peruse the "Designing For Performance" benchmarks in your browser.

But there was no point in changing the structure of legacy content.

The performance can be related to having String required to be stored. There is significant difference between the creation of a single class for every constants vs. multiple enums.

For example in Java 7 when you have a enum with two fields you need 44 items in poll constant and for a class with two static final integers you need only 17.

What is the difference

class ContantField {
  public static final int f1 = 0;
  public static final int f2 = 1;
}

enum ContantEnum {
  E1,E2
}

This two declarations are very different in the way there are stored and used. The simplification of ContantEnum could look like

class ContantEnum {
   public static final Enum enum0    = new Enum("V1",0);
   public static final Enum enum1    = new Enum("V2",1);
   public static final Enum[] values = new Enum[] {enum0,enum1};
} 

By this simplification you can notice that enum require more memory resources than int.

To answer your question, it must be understood the role of enums. One role of enum is to increase compile time type safety.

To point that out see this example:

public void setImportantThing(int priviledge, int rights)

public void setImportantThing(Privilege p, Right r)

In the case of int we can pass any value that is an int. In he tcase of enum we are forced to use the proper one.

The case we have here is trade off between compile time validation and memory usage on runtime. You should decide for yourself when you should use enum and where static int is sufficiently secure.

Note: enum was introduced to Java in version 1.5, using them before this was quite problematic more.

In Android Studio Beta, the developer will be able to enforce type safety using annotation.

Οurous
  • 348
  • 6
  • 17
6

Enums are:

  • Safer - more resilient to change.

    A change to the list of enums is more likely to cause compile-time errors if the change was mistaken.

  • Clearer - most developers will instantly understand that the items are connected in some way.

    enum { A, B, C } is much more obviously a group of items with a connection than psfi A = 0; psfi B = 1; psfi C = 2;

So unless you have a measurable advantage to using public static final int, be it in memory footprint or speed, you should always use enum.

See When is optimisation premature?

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
1

Basically the Android core is C/C++ code. This works with integers. So when using enums in Java every value had to be "translated". This would cost CPU time and memory. Both are rare on embedded systems.

brummfondel
  • 1,202
  • 1
  • 8
  • 11
  • 2
    The Java is translated to byte code. Then byte code is translated to dalvik byte code. Dalvik byte code is executed via dalvik VM. The enum could be represeted as integer. There is an overhead on enum that use String string. Its more probable that this was the cause. That with enum you need to store their names not only integers. – Damian Leszczyński - Vash Jun 30 '14 at 13:47
  • 1
    But you have to store the integer value with every enum which needs memory again. Java does not give a numeric value to an enum like C does. – brummfondel Jun 30 '14 at 13:49
  • Thank you! That is really reasonable! – JaskeyLam Jun 30 '14 at 13:52
  • @brummfondel. The int is not the case here. When you declare enum in C or java you need to store some bytes for numeric value. Java gives as numeric value for an enum. The constructor requires a string and integers. The difference did not came from the int, but with that string. Enum creation requires more memory. So the issue is not that a translation is requires but more memory is used. – Damian Leszczyński - Vash Jun 30 '14 at 14:13
  • As I wrote, more memory. So what's your problem here? Beside that Java can give a numeric value if you specify one as member otherwise there is no number - or any "random" hash id. – brummfondel Jun 30 '14 at 14:16
1

Simply put Enums use more resources then public static final fields so don't use ENUM in mobile programing where every byte counts.

http://developer.android.com/training/articles/perf-tips.html#UseFinal

danny117
  • 5,581
  • 1
  • 26
  • 35
0

When I'm programming personally, I use your method above when I wish to have a name represent an important integer. For example, MAX_INT which could map to int 50. This is useful because I can change the int to 60 if I wish without having to go through all of my code and change my 50s to 60s.

With an enum, it is (as this link explains) a special data type that enables for a variable to be a set of predefined constants. Therefore, this would be an ideal choice if you wanted to have a restricted set of values to choose from - whereas your chosen style above would be expandable and, as stated, easy to exploit by choosing a value not in bounds.