1) I’m aware of the following benefits:
they increase the level of abstraction since you immediately see what underlying integral values represent.
You can use them instead of magic numbers and by doing that making the code more understandable
They also restrict the values an enum
variable can have and in doing so make the application safer, since programmers know which values are valid for variable, so I guess they sort of provide a type safety
Are there any other benefits they provide over directly using integral values?
2) Why do they use integrals as an underlying type and not string?
thank you
The benefits of using enumerations include: Reduces errors caused by transposing or mistyping numbers. Makes it easy to change values in the future. Makes code easier to read, which means it is less likely that errors will creep into it.
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.
Enums are lists of constants. When you need a predefined list of values which do represent some kind of numeric or textual data, you should use an enum. You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values.
Java Enums provide many features that integer constants cannot. Enums can be considered as final classes with a fixed number of instances. Enums can implement interfaces but cannot extend another class. While implementing the strategy pattern, we can use this feature of Enums.
You've listed a lot of the core reasons where enums are preferable to integral types.
Named constants are safer and more readable than magic numbers
Enums describe to programmers what they are for. Integral values don't.
Naturally limiting the set of values that can be passed in. (You've got the tip of the type-safety iceberg... but look deeper...)
You can also add:
Vastly increased Type Safety. If you accept an 'int', then any int can be passed in. If you accept a VehicleType, then only a VehicleType can be passed in. I'm not just talking about someone passing in 6 when the largest allowed number is 5. I mean what if you pass in FuelType.Unleaded to a function that thinks it means VehicleType.Aeroplane? With enums the compiler will tell you you're an idiot. An integral type says "yeah, 5 is fine with me" and your program exhibits really odd behaviour that may be extremely difficult to trace.
Easier refactoring. Just as with any magic constants, If you pass in the value 5 in a hundred places in your program, you're in trouble if you decide to change 5 to have a different meaning. With an enum (as long as you don't have binary backwards compatibility concerns) you can change the underlying values. You can also change the underlying type of an enum if you wish (byte -> int -> long) without having to do anything more than recompile the client code.
Bitfields are so much easier to work with when the bits and masks can be named. And if you add new bits, you can often arrange things so that merely updating the related masks will allow most of your existing code to handle the new bitfields perfectly without having to rewrite them from scratch.
Consistency throughout the program. If you are careful with obfuscation and type safety, enums allow you to represent a list of named values that a user chooses from with the same names in the code, but without the efficiency cost of using strings.
Everybody understands why constants are great in code. Enums simply give you a way of holding together a related group of constants. You could achieve the same thing in a messier manner using a namespace of consts.
Using an enum for a parameter rather than a bool not only makes the code self-documenting, readable, and less prone to mistakes. It also makes it much easier to add a third option when you realize that two options isn't enough.
As with all tools, enums can be misused. Just use them where they make sense.
2) Why use bytes or ints instead of strings? Simply they're small and efficient.
I would conjecture that they require underlying integral types to ensure simplicity of comparison and more easily support bit flags. Without that limitation, we, or the compiler, or the runtime, would likely have to resort to some fuzziness to do things like combinations - or we would get into a situation where - as you say - we shouldn't care about the underlying type (the point of the abstraction) and yet when we try to say A | B
we get a runtime error because we used an underlying type that isn't capable of that type of operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With