Java: Enum VS. Int

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 final else 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 and GREEN both have the same value 3

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 enums 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 enums 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

  1. supported by PostgreSQL for Create Data Type.

  2. static data with ordered set values (Which is can be sort by PostgreSQL)

  3. case sensitive 'happy' is not same with 'HAPPY'
  4. 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



Leave a reply



Submit