Java: Enum vs. Int
Both ints
and enums
can use both switch or if-then-else, and memory usage is also minimal for both, and speed is similar - there's no significant difference between them on the points you raised.
However, the most important difference is the type checking. Enums
are checked, ints
are not.
Consider this code:
public class SomeClass {
public static int RED = 1;
public static int BLUE = 2;
public static int YELLOW = 3;
public static int GREEN = 3; // sic
private int color;
public void setColor(int color) {
this.color = color;
}
}
While many clients will use this properly,
new SomeClass().setColor(SomeClass.RED);
There is nothing stopping them from writing this:
new SomeClass().setColor(999);
There are three main problems with using the public static final
pattern:
- The problem occurs at runtime, not compile time, so it's going to be more expensive to fix, and harder to find the cause
- You have to write code to handle bad input - typically a
if-then-else
with a finalelse throw new IllegalArgumentException("Unknown color " + color);
- again expensive - There is nothing preventing a collision of constants - the above class code will compile even though
YELLOW
andGREEN
both have the same value3
If you use enums
, you address all these problems:
- Your code won't compile unless you pass valid values in
- No need for any special "bad input" code - the compiler handles that for you
- Enum values are unique
Another enum vs. int
Consideration
With enum you define a type having some constants themselves "typed" (not the good word by I don't know how to say that).
The advantage between using enum values and constants is to be able to parse the values and to use the enum scope as a type.
So it is a better abstraction.
Also you don't need to care to define the values even if you can.
For example:
Parsing enum values
foreach ( var value in Enum.GetValues(typeof(Token) ) ...
Passing enum parameter
void Method(Token token) ...
Declare a collection keyed by an enum
var map = new Dictionary<Token, string>();
Condition test
if ( value == Token.INFORMATIONAL ) ...
Easy of bit flags usage
https://learn.microsoft.com/en-us/dotnet/api/system.flagsattribute
Default item name ToString result
Console.WriteLine(Token.INFORMATIONAL)
Will display the name of the value, not its value as for a constant.
So to display the value:
Console.WriteLine((int)Token.INFORMATIONAL)
Conclusion
With constants, you need to use reflexion to parse a list but it is ugly and not usefull at all and you can't pass them as a typed parameter.
Usage possibilities of constants is limited.
So enums and constants are not the same thing at all even the basic as int usage.
Thus using enum or constants depends on the usage you will do.
If you only need int values and don't care about segregation, choose constants.
If you care about type safety and need to do advanced things, choose enum.
One last word to say is that enum is to not care about the underlying value, so if you need to work with values, use constants, else enum.
Use what is the most natural thing.
When to use Enum / Int Constants
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.
Java enum (or int constants) vs c enum
My feeling is that in purposes only for switch
statement enum
is superfluous in your case, and it is better simply using final static int
constants. For instance of memory economy.
Also, Joshua Bloch in his Effective Java
recommends using enum
s instead of int
constants in his Item 30: Use enums instead of int constants
. But IMHO it is correct way of enum
using for more complicated cases then just replacing c
#define
construction.
UPDATE: as author mentioned in his comment to this my answer, he is wondering is use if enum
is better then int
constants in general. In this case such question becomes duplicate (see Java: Enum vs. Int), and my answer will: in general enum
s are better, and why - look at Joshua Bloch's Item 30
, as I mentioned before.
Java Enum return Int
Font.PLAIN is not an enum. It is just an int
. If you need to take the value out of an enum, you can't avoid calling a method or using a .value
, because enums are actually objects of its own type, not primitives.
If you truly only need an int
, and you are already to accept that type-safety is lost the user may pass invalid values to your API, you may define those constants as int
also:
public final class DownloadType {
public static final int AUDIO = 0;
public static final int VIDEO = 1;
public static final int AUDIO_AND_VIDEO = 2;
// If you have only static members and want to simulate a static
// class in Java, then you can make the constructor private.
private DownloadType() {}
}
By the way, the value
field is actually redundant because there is also an .ordinal()
method, so you could define the enum
as:
enum DownloadType { AUDIO, VIDEO, AUDIO_AND_VIDEO }
and get the "value" using
DownloadType.AUDIO_AND_VIDEO.ordinal()
Edit: Corrected the code.. static class
is not allowed in Java. See this SO answer with explanation and details on how to define static classes in Java.
Enum vs String/Integer Enum
Enum in PostgreSQL
supported by PostgreSQL for Create Data Type.
static data with ordered set values (Which is can be sort by PostgreSQL)
- case sensitive 'happy' is not same with 'HAPPY'
- Cannot input other values if not created in data type.
For Performance issue: PostgreSQL never has performance issue cause by data-type. most of them cause by indexing, configuration, and bad database design.
For Enum: in PostgreSQL They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.
The translations from internal enum values to textual labels are kept in the system catalog pg_enum
. Querying this catalog directly can be useful.
Note: both Native or String/Integer based type enum can't cause performance issue.
Hibernate - Enum vs Int
Use @Enumerated(EnumType.ORDINAL)
, and you'll have the enum in your entities, mapped as the ordinal int value in the database table. That's the default mapping for enums, if I'm not mistaken, so you can even remove the @Enumerated
annotation, and Hibernate will persist the enum as an int automatically.
PS: you should also respect the Java naming conventions: item_type
should be itemType
, and getItem_type()
should be getItemType()
.
Enumerations vs int flags?
I very much doubt you'd see performance benefits - and in some cases there may even be performance penalties, depending on how you're using them. I doubt they'd be significant though.
The benefit isn't in terms of performance - it's in terms or expressing your intentions more clearly, leading to more readable (and type-safe) code. For example, with integer flags nothing's going to complain if you try to use (say) HTTP_STATUS_UNAUTHORIZED as a value for your file sharing mode in a method call... whereas if both of those were enums, the parameter would be strongly typed to really only allow file sharing modes (or null, admittedly, assuming you are talking about Java).
Related Topics
Creating an Animated 4X4 Grid in Java
Why Are Class Static Methods Inherited But Not Interface Static Methods
How to Read an Aws S3 File with Java
Find Duplicate Element in Array in Time O(N)
How to Disable the Default Console Handler, While Using the Java Logging API
Locally Declared Variables Can Not Be Inspected
How to Compile Multiple Java Source Files in Command Line
Using a Prepared Statement and Variable Bind Order by in Java with Jdbc Driver
Java Static Initialization Order
Java Creating a New Objectinputstream Blocks
Closing Bufferedreader and System.In
What's the Purpose of Meta-Inf
Why Shouldn't Java Enum Literals Be Able to Have Generic Type Parameters
Converting Date-String to a Different Format
When Not to Use the Static Keyword in Java
Fastest Way to Iterate an Array in Java: Loop Variable VS Enhanced for Statement
How to Properly Do a Background Thread When Using Spring Data and Hibernate