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? tho
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.
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.
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?
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
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.