7
enum Drill{
        ATTENTION("Attention!"), AT_EASE("At Ease");    
        private String str; 
        private Drill(String str){
            this.str = str;
        }
        public String toString(){
            return str;
        }
    }
public class EnumExample {
    public static void main(String[] args) {
            Drill d1= Drill.valueOf("ATTENTION");
            Drill d2= Drill.valueOf("ATTENTION");
            **System.out.println(d1.equals(d2));//TRUE
            System.out.println(d1==d2);//TRUE**
            System.out.println(Drill.ATTENTION.equals(Drill.valueOf("ATTENTION")));
            System.out.println(Drill.ATTENTION.equals(Drill.AT_EASE));//FALSE 
            System.out.println(Drill.ATTENTION==Drill.valueOf("ATTENTION"));//TRUE
            System.out.println(Drill.ATTENTION==Drill.AT_EASE);//FALSE
}
}

Enum behaviour while using == and equals() seems to be same. According to my knowledge, == just check references. Therefore d1 == d2 should be FALSE. Can anyone explain this behavior why is is TRUE?

user3781572
  • 175
  • 1
  • 4

5 Answers5

6

== should work fine with enums because there aren't multiple references of a given enum item; there's just one. The Java Language Specification section on enum types, 8.9 states that they are implicitly static and final and so can only be created once.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

You are comparing enum constants. This means that for each enum constant, there is a single instance created.

This

enum Drill{
    ATTENTION("Attention!"), AT_EASE("At Ease"); 
    ...
}

is more or less equivalent to

final class Drill {
    public static final Drill ATTENTION = new Drill("Attention!") {};
    public static final Drill AT_EASE = new Drill("At Ease") {};
    ...
}

The valueOf method

/**
* Returns the enum constant of this type with the specified
* name.
* The string must match exactly an identifier used to declare
* an enum constant in this type.  (Extraneous whitespace 
* characters are not permitted.)
* 
* @return the enum constant with the specified name
* @throws IllegalArgumentException if this enum type has no
* constant with the specified name
*/
public static E valueOf(String name);

returns the value of instance referred to by the variable whose name equals the specified String value.

So

Drill.valueOf("ATTENTION") == Drill.ATTENTION

for every invocation of valueOf with that String value.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

Enum Types from the documentation,

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. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.

Because they are constants, the names of an enum type's fields are in uppercase letters.

Drill d1= Drill.valueOf("ATTENTION"); // ATTENTION
Drill d2= Drill.valueOf("ATTENTION"); // ATTENTION

So d1 == d2 and d1.equals(d2) because they refer to the same constant value and that is Drill.ATTENTION.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 2
    edited for i.e. v. e.g. It makes a big difference in technical documentation pretty often so thought I should correct. – djechlin Jul 02 '14 at 02:27
0

The JVM is organized so that it is impossible or effectively impossible to instantiate more than one instance of each enum constant. http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

When you call valueOf, it just returns the enum constant that has been already instantiated.

Strikeskids
  • 3,932
  • 13
  • 27
0

In an enum, all items are singletons: they are constructed once (for the sake of simplicity at the beginning of execution, mostly when needed). Thus they follow the Singleton pattern (probably one of the only good reasons to use a singleton).

Thus in memory, there is one instance for every element in the enum.

The valueOf method merely acts as a Flyweight: the JVM keeps some kind of dictionary and returns the appropriate enum item instance.

On a sidenote, I think it is still advisable to use the equals method since this offers the programmer the chance to define equality partitions on the items of the enum. (say A and B are equal, but have some different behavior).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555