Java enum values - java

How is the value of an enum calculated? Does the compiler give it a static value? What kind of value is it?
The reason I ask is because I was wondering what the consequences of using enum values over a tcp (or any inter-process) connection would be. (By enum value I mean Enum.VALUE) Obviously you wouldn't be able to construct packets compatible with your program from another language unless you knew the pre-determined values of each enum. So is it possible to figure out the "real" values of each? And will two Java programs using the same enum "class" file understand each other?
This is purely theoretical, please no scoldings. Pointers are good, though.

As has been explained, don't rely on underlying implementations. Instead, design your enum to store this sort of information under your control. Imagine you have three commands to send to some embedded controller, done by writing a bit pattern to a register. You want to use enums to give you a high-level representation of the commands, but at some point you need those pesky bit patterns:
public enum EmbeddedControllerCommand {
FOO(0x001), BAR(0x010), BAZ(0x100);
private int bitPattern = 0;
EmbeddedControllerCommand(int bitPattern) {
this.bitPattern = bitPattern;
}
public int getBitPattern() {
return this.bitPattern;
}
}
Just call EmbeddedControllerCommand.FOO.getBitPattern() to get the command pattern for the FOO command.

in Java Enums do have integer reference that Java calls ordinal. For example you can do yourEnumVariable.ordinal() to get the int number of the enum variable. The numbers are assigned in a way that first in the list gets number 0, second number 1 and so on.
However in your case it sounds like you should not be concerned about what is the internal representation of enums. You should decide on what kind of protocol you will use to transfer information. After that you can think of how to transfer enum values. You'll probably have to anyway build some mapping classes for the protocol to map from Java to the protocol.

If you refer to the Enum JavaDoc you can read that the Enum.ordinal() method returns a numeric constant value which is determined by the order of the Enum declarations in the class file.
For example, consider these enum constants in alphabetical order:
public enum Fruit{
APPLE, // APPLE.ordinal() == 0
ORANGE;// ORANGE.ordinal() == 1
PEAR, // PEAR.ordinal() == 2
}
But if we add BANANA in its alphabetical position, see how the values would change, breaking any code that relies on them:
public enum Fruit{
APPLE, // APPLE.ordinal() == 0
BANANA,// BANANA.ordinal() == 1
ORANGE;// ORANGE.ordinal() == 2
PEAR, // PEAR.ordinal() == 3
}
This means that, so long as you're using the same version of the source code, you can rely on the underlying value being the same, and can use it for situations where there are no other options. I say no other options because by making your code dependent on the order of the enums, it makes the code more fragile, whereas if you aren't relying on the ordinal value you can reorder existing or insert new enum constants at will.
Now, would you accept a mild scolding for not reading the JavaDocs thoroughly before post? :)

You should not rely the pre-assinged value of enum given by Java compiler. Different language has different scheme to deal with enum. In Java, enum can be treated like a class and objects (not exactly for the same purpose) so you can create a constructor in your enum and initialize the enum to the value you want. Here is a fairly clear examples:
http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

Related

Enum or List or Set : Which is better to use [duplicate]

I am aware there are similar questions, and I have read the answers, but maybe I'm just not quite grasping the full difference of its use, even though I understand their difference when for example, initializing a String. Example:
String[] favorite = {"dog", "cat", "alien"};
vs
enum favorite = {dog, cat, alien}
Or maybe the use of either in the above case is similar, but their difference can be grasped better in another example? Is it that enum can clearly store more properties for a variable when creating the class?
The big advantage of enum is that the compiler checks for typos (type safety). For instance, if you assign the value "dag" to a string, the compiler does not complain. But, you cannot assign the value favorite.dag to a variable (of type favorit). Also, enum makes the code more readable and it is faster (comparison, for instance).
Just like #AhmadWabbi said, it's mostly type safety.
With enums you also have the ability to write methods corresponding to the enum.
For instance:
public enum Favorite = {
dog("woof"),
cat("meow"),
alien("zoink")
private String sound;
Favorite(String sound) {
this.sound = sound;
}
public String makeSound() {
return sound;
}
}
Which then let you call the method on a known enum (Favorite.dog.makeSound()) or if the enum is a parameter to another method.
The biggest advantage is that an enum is type-safe. An enum value can only take on one of the defined values (or null). (Note that an enum in Java is not like an enum in C++ or C#, where it is more like an alias for an int).
If you use a type like String or int, you can assign to that any value that fits in a String or int, even if it's not one of the limited set of values that you want it to contain.
It also makes programs easier to read, because when for example a method takes an enum type as a parameter, you immediately know what it means, and what values are valid - if it would, for example, take a String, you don't automatically know which strings are valid inputs and which are not.
There is no need to be too sophisticated with a program.
If you have three strings use the string array. If you have three distinct entities which differ by something else in addition to their names, use enum (on which you, evidently, will then be operating somehow).
Enums are easy to add new functionality to your code. Strings have their limits, you can decide yourself if you need all the benefits of enums or string will do for the job.
For example:
public enum favourite {
dog, cat, cow;
public boolean barking(){
switch(this){
case dog:
return true;
case cat:
case cow:
return false;
}
throw new AssertionError();
}
}
Enum sort of create a namespace . Thus two constants with same name can belong to different enums. Of course , you can emulate it with ArrayList but its not intuitive , because its supposed to acts as a container rather than a logical namespace holding constants.
You can compare it old style enums from C++ , where two enum declarations holding a same named constant shows a error . With new style class enums in c++ adds sort of namespace to it , which was not possible earlier.
And yes
Enums in Java already have a name-spacing feature.
By the way , Enum and ArrayList both have different purpose.
The biggest advantage of enums is that they are type-safe: a variable of an enum type can only hold values defined in that enum. By the way, in some circumstances this can be a big disadvantage, a show-stopper even: if the possible values are not known at compile time (for example, because you need to fetch them from a database at run-time) you cannot use enums.
Although I do not see a clear advantage of it (and if I don't see a clear advantage I would always use the established coding practice, which is using an enum), you can certainly use strings as a kind of enums. Performance will probably be a bit worse because of the string comparisons, but in most cases unnoticeably so.
However, I would strictly advice against your array example, for the following reasons:
Arrays are mutable. If your project is large enough, someone will eventually write favorites[0] = "beer"; and thus cause mysterious bugs in unrelated parts of the code.
Using an array has no advantage in readability. The meaning String myFavorite = favorites[1]; is completely opaque, whereas String myFavorite = "cat"; or Favorite myFavorite = Favorite.CAT; are immediately clear.
String literals can be used in switch statements, but not expressions like favorites[2]. So switch (myFavorite) { case favorites[2]: ... } is not legal Java (whereas switch (myFavorite) { case "alien": ... } is).
If you really want to use Strings as enums, then define String constants:
public static final String FAV_DOG = "dog";
public static final String FAV_CAT = "cat";
public static final String FAV_ALIEN = "alien";

how to make a string variable to have only few predefined values in java

I want to create a class that define a string variable which can have only few predefined value.
public class Constraint{
String const; // I want this constraint value to be fixed to either of {greaterthan,lesserthan,greaterthanequalto or lesserthanequalto}
public Constraint(String const){
this.const = const;
}
}
Program should throw an error if any other value is sent.
I wan to use something like enum over here, but i want to do so for Strings.
The concept you are looking for is called Enum.
Simply do not try to re-invent a less powerful, less "standard" workaround.
Seriously: enums give you compile time safety. Use them.
The alternative would be that your "constant" class contains a final, fixed Set of "valid" strings; and you simply check in your "setter" that incoming strings are listed in that Set. And of course, you should make sure that users of your constant class can access the content of that Set, so they can "know" those valid strings when they need to.

Byte-size enum in Java

I have a class of which there may be many instances (on a mobile device), so I'm trying to minimize the size. One of my fields is a "DrawTarget" that indicates whether drawing operations are being ignored, queued to a path or drawn to the display. I would like it to take a single byte or less since there are only 3 possible values, but I would also like it to be friendly code so I don't have hard-coded numbers all over. One thought is to use an enum like:
public enum DrawTarget {
Invisible,
Path,
Canvas
}
But from what I read, a Java enum doesn't allow you to specify the memory layout -- I can't request that the enum values represent a byte-size value -- and I guess enum values end up being integer-sized values in Java.
So I thought about maybe making an implicit conversion operator in the enum... is this possible in Java? Or is my best option to implement something like this within the enum:
public static DrawTarget fromValue(byte value) {
switch (value) {
case 0:
return Invisible;
case 1:
return Path;
default:
return Canvas;
}
}
and then call DrawTarget.fromValue wherever I want to access the value?
Or should I just create a single-byte class since apparently (from what I read in my research on this) enums are basically just special classes in Java anyway?
public class DrawTarget {
public static final byte Invisible = 0;
public static final byte Path = 1;
public static final byte Canvas = 2;
}
But how to I represent the value of an enum instance if I use that last solution? I still need a way to allow the "=" operator to accept one of the static fields of the class... like a conversion constructor or an assignment operator overload.
I suspect, however, that any class object, being a reference type, will take more than a byte for each instance. Is that true?
In Java enum is a class that has as many instances, as there are values. The instances are produced at class (enum) loading time. Each place where you use an enum variable or an enum attribute, you actually use an ordinary reference to one of the existing enum objects (instances of enums are never created after enum is initialized).
This means that an enum reference costs as much as any other object reference, usually four bytes. Which is really, really, really little.
You don't know how much memory does a byte take (really! remember that low level memory management includes plenty of padding!), so any "optimization" based on this will fail. On a given architecture a byte field might take as much memory as an integer field (because it might be faster that way).
If you want to write good Java, use enum. Really. The only good reason not to use enums, would be if you had a whole array of values, like: drawTargets[] = new DrawTarget[100000];
If you insist on microoptimizing, just use plain bytes and forget enums; public static final byte SOMETHING = 1; is fine for making comparisons (and sucks for debugging).
I have written Android programs for a long time and have never seen such microoptimization pay off. Your case might be the one in a million, but I don't think it is.
Also, to make life simpler for all of us, please consider using Java conventions in Java code: enum instances and public final static fields should be names LIKE_THIS, attributes likeThis (not LikeThis!).
and I guess enum values end up being integer-sized values in Java.
No, enums are always classes in Java. So if you have a field of type DrawTarget, that will be a reference - either to null or to one of the three instances of DrawTarget. (There won't be any more instances than that; it's not like a new instance of DrawTarget is created every time you use it.)
I would go with the enum and then measure the memory usage - an enum is logically what you want, so take the normal approach of writing the simplest code that works and then testing the performance - rather than guessing at where bottlenecks might be.
You may want to represent the value as a single byte when serializing, and then convert it back to the enum when deserializing, but other than that I'd stick with the enum type throughout your code if possible.
Unless android has some special way of treating enum references, each reference to a DropTarget will indeed take more than one byte in memory. Enums are classes, and enum instances are objects. So a reference to an enum instance takes the same amout of memory as any other object reference.
I wouldn't care much about it unless you have measured that this caused memory problems, though, and that reducing the size would have a significant impact.
What you get from enums, mainly, is type safety. If a method takes a DropTarget as argument, you (or coworkers) won't be able to pass anything other than one of the three instances of DropTarget (or null). If you use a byte instead, the code is less clear, and anyone could pass any byte value instead of the three authorized byte values.
So, decide which is the most important for you, and choose the solution you prefer.
Your classes will only contain a reference to the enum. Only one instance of each enum will be created.
Aside from that, consider using polymorphism to implement the drawing behavior.
If the value of the enum is fixed, instantiate a different subclass for each object depending on its desired drawing behavior.
If the value changes often, you could keep a reference to the desired drawing strategy in the object. Refer to an object with an empty draw() method for objects that should not be drawn. Etc.
enum is special data type, not a class.check oracle documentations for further details.
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.

Java enumerations vs. static constants

I'm looking at some Java code that are maintained by other parts of the company, incidentally some former C and C++ devs. One thing that is ubiquitous is the use of static integer constants, such as
class Engine {
private static int ENGINE_IDLE = 0;
private static int ENGINE_COLLECTING = 1;
...
}
Besides a lacking 'final' qualifier, I'm a bit bothered by this kind of code. What I would have liked to see, being trained primarily in Java from school, would be something more like
class Engine {
private enum State { Idle, Collecting };
...
}
However, the arguments fail me. Why, if at all, is the latter better than the former?
Why, if at all, is the latter better
than the former?
It is much better because it gives you type safety and is self-documenting. With integer constants, you have to look at the API doc to find out what values are valid, and nothing prevents you from using invalid values (or, perhaps worse, integer constants that are completely unrelated). With Enums, the method signature tells you directly what values are valid (IDE autocompletion will work) and it's impossible to use an invalid value.
The "integer constant enums" pattern is unfortunately very common, even in the Java Standard API (and widely copied from there) because Java did not have Enums prior to Java 5.
An excerpt from the official docs, http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html:
This pattern has many problems, such as:
Not typesafe - Since a season is just an int you can pass in any other int value where a season is required, or add two seasons together (which makes no sense).
No namespace - You must prefix constants of an int enum with a string (in this case SEASON_) to avoid collisions with other int enum types.
Brittleness - Because int enums are compile-time constants, they are compiled into clients that use them. If a new constant is added between two existing constants or the order is changed, clients must be recompiled. If they are not, they will still run, but their behavior will be undefined.
Printed values are uninformative - Because they are just ints, if you print one out all you get is a number, which tells you nothing about what it represents, or even what type it is.
And this just about covers it. A one word argument would be that enums are just more readable and informative.
One more thing is that enums, like classes. can have fields and methods. This gives you the option to encompass some additional information about each type of state in the enum itself.
Because enums provide type safety. In the first case, you can pass any integer and if you use enum you are restricted to Idle and Collecting.
FYI : http://www.javapractices.com/topic/TopicAction.do?Id=1.
By using an int to refer to a constant, you're not forcing someone to actually use that constant. So, for example, you might have a method which takes an engine state, to which someone might happy invoke with:
engine.updateState(1);
Using an enum forces the user to stick with the explanatory label, so it is more legible.
There is one situation when static constance is preferred (rather that the code is legacy with tonne of dependency) and that is when the member of that value are not/may later not be finite.
Imagine if you may later add new state like Collected. The only way to do it with enum is to edit the original code which can be problem if the modification is done when there are already a lot of code manipulating it. Other than this, I personally see no reason why enum is not used.
Just my thought.
Readabiliy - When you use enums and do State.Idle, the reader immediately knows that you are talking about an idle state. Compare this with 4 or 5.
Type Safety - When use enum, even by mistake the user cannot pass a wrong value, as compiler will force him to use one of the pre-declared values in the enum. In case of simple integers, he could even pass -3274.
Maintainability - If you wanted to add a new state Waiting, then it would be very easy to add new state by adding a constant Waiting in your enum State without casuing any confusion.
The reasons from the spec, which Lajcik quotes, are explained in more detail in Josh Bloch's Effective Java, Item 30. If you have access to that book, I'd recommend perusing it. Java Enums are full-fledged classes which is why you get compile-time type safety. You can also give them behavior, giving you better encapsulation.
The former is common in code that started pre-1.5. Actually, another common idiom was to define your constants in an interface, because they didn't have any code.
Enums also give you a great deal of flexibility. Since Enums are essentially classes, you can augment them with useful methods (such as providing an internationalized resource string corresponding to a certain value in the enumeration, converting back and forth between instances of the enum type and other representations that may be required, etc.)

Can I add and remove elements of enumeration at runtime in Java

It is possible to add and remove elements from an enum in Java at runtime?
For example, could I read in the labels and constructor arguments of an enum from a file?
#saua, it's just a question of whether it can be done out of interest really. I was hoping there'd be some neat way of altering the running bytecode, maybe using BCEL or something. I've also followed up with this question because I realised I wasn't totally sure when an enum should be used.
I'm pretty convinced that the right answer would be to use a collection that ensured uniqueness instead of an enum if I want to be able to alter the contents safely at runtime.
No, enums are supposed to be a complete static enumeration.
At compile time, you might want to generate your enum .java file from another source file of some sort. You could even create a .class file like this.
In some cases you might want a set of standard values but allow extension. The usual way to do this is have an interface for the interface and an enum that implements that interface for the standard values. Of course, you lose the ability to switch when you only have a reference to the interface.
Behind the curtain, enums are POJOs with a private constructor and a bunch of public static final values of the enum's type (see here for an example). In fact, up until Java5, it was considered best-practice to build your own enumeration this way, and Java5 introduced the enum keyword as a shorthand. See the source for Enum<T> to learn more.
So it should be no problem to write your own 'TypeSafeEnum' with a public static final array of constants, that are read by the constructor or passed to it.
Also, do yourself a favor and override equals, hashCode and toString, and if possible create a values method
The question is how to use such a dynamic enumeration... you can't read the value "PI=3.14" from a file to create enum MathConstants and then go ahead and use MathConstants.PI wherever you want...
I needed to do something like this (for unit testing purposes), and I came across this - the EnumBuster:
http://www.javaspecialists.eu/archive/Issue161.html
It allows enum values to be added, removed and restored.
Edit: I've only just started using this, and found that there's some slight changes needed for java 1.5, which I'm currently stuck with:
Add array copyOf static helper methods (e.g. take these 1.6 versions: http://www.docjar.com/html/api/java/util/Arrays.java.html)
Change EnumBuster.undoStack to a Stack<Memento>
In undo(), change undoStack.poll() to undoStack.isEmpty() ? null : undoStack.pop();
The string VALUES_FIELD needs to be "ENUM$VALUES" for the java 1.5 enums I've tried so far
I faced this problem on the formative project of my young career.
The approach I took was to save the values and the names of the enumeration externally, and the end goal was to be able to write code that looked as close to a language enum as possible.
I wanted my solution to look like this:
enum HatType
{
BASEBALL,
BRIMLESS,
INDIANA_JONES
}
HatType mine = HatType.BASEBALL;
// prints "BASEBALL"
System.out.println(mine.toString());
// prints true
System.out.println(mine.equals(HatType.BASEBALL));
And I ended up with something like this:
// in a file somewhere:
// 1 --> BASEBALL
// 2 --> BRIMLESS
// 3 --> INDIANA_JONES
HatDynamicEnum hats = HatEnumRepository.retrieve();
HatEnumValue mine = hats.valueOf("BASEBALL");
// prints "BASEBALL"
System.out.println(mine.toString());
// prints true
System.out.println(mine.equals(hats.valueOf("BASEBALL"));
Since my requirements were that it had to be possible to add members to the enum at run-time, I also implemented that functionality:
hats.addEnum("BATTING_PRACTICE");
HatEnumRepository.storeEnum(hats);
hats = HatEnumRepository.retrieve();
HatEnumValue justArrived = hats.valueOf("BATTING_PRACTICE");
// file now reads:
// 1 --> BASEBALL
// 2 --> BRIMLESS
// 3 --> INDIANA_JONES
// 4 --> BATTING_PRACTICE
I dubbed it the Dynamic Enumeration "pattern", and you read about the original design and its revised edition.
The difference between the two is that the revised edition was designed after I really started to grok OO and DDD. The first one I designed when I was still writing nominally procedural DDD, under time pressure no less.
You can load a Java class from source at runtime. (Using JCI, BeanShell or JavaCompiler)
This would allow you to change the Enum values as you wish.
Note: this wouldn't change any classes which referred to these enums so this might not be very useful in reality.
A working example in widespread use is in modded Minecraft. See EnumHelper.addEnum() methods on Github
However, note that in rare situations practical experience has shown that adding Enum members can lead to some issues with the JVM optimiser. The exact issues may vary with different JVMs. But broadly it seems the optimiser may assume that some internal fields of an Enum, specifically the size of the Enum's .values() array, will not change. See issue discussion. The recommended solution there is not to make .values() a hotspot for the optimiser. So if adding to an Enum's members at runtime, it should be done once and once only when the application is initialised, and then the result of .values() should be cached to avoid making it a hotspot.
The way the optimiser works and the way it detects hotspots is obscure and may vary between different JVMs and different builds of the JVM. If you don't want to take the risk of this type of issue in production code, then don't change Enums at runtime.
You could try to assign properties to the ENUM you're trying to create and statically contruct it by using a loaded properties file. Big hack, but it works :)

Categories

Resources