Reputation: 1065
I created one Enum class:
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
I am trying to use it in a main() method:
System.out.println(Currency.NICKLE.DIME.PENNY.QUARTER);
System.out.println(Currency.PENNY.QUARTER);
There is no error being generated by this. It prints the constant which is at the last.
Could somebody please explain it?
Upvotes: 4
Views: 368
Reputation: 3654
I'll try to add on a bit more to what has been said in the comments above.
Enum values are somewhat special. From the Wikipedia entry on Java enums:
An enum type in Java is actually a special compiler-generated class rather than an arithmetic type, and enum values behave as global pre-generated instances of that class. Enum types can have instance methods and a constructor (the arguments of which can be specified separately for each enum value).
So, while they are only generated once at compile time, they are special instances of the given enum type. As such, it has access to other members of the class. Note that this also implies that you cannot instantiate an enum type yourself (i.e. using new
).
From one instance of enum class you can access another instance of same enum class? Which I haven't seen in normal Java class.
This is also possible in a normal class, though frowned upon as it offers no real benefits and might even cause problems and bugs (through NullPointerException
s).
Consider the following two classes:
public class SomeClass
{
public final static int MODE = 1;
private String message;
public SomeClass(String message)
{
this.message = message;
}
}
public class Test
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass("bla");
System.out.println(myObject.MODE);
System.out.println(OtherClass.MODE);
}
}
This would simply print out:
1
1
However, imagine that you are performing some task where you iterating through a list of SomeClass
objects where some of the entries are potentially null
(perhaps because they were removed from the collection at some point, or because null
entries were allowed at insertion time for whatever reason).
In that case, if you were to access the static
member through an instance, you would get an NPE, whereas accessing it through the class itself would work as expected.
Note that the behaviour that is described in the question is specific to enum
types themselves (i.e. Currency.NICKLE.DIME...
). There is a way to mimic that behaviour, as follows:
public class SomeClass
{
public static SomeClass REF; // not final anymore since 'this' must be the first line in a constructor call
public String message; // note this is public now
public SomeClass(String message)
{
this.message = message;
}
public void setRef() {
REF = this;
}
}
public class Test
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass("bla!");
System.out.println(myObject.REF);
System.out.println(SomeClass.REF);
myObject.setRef();
System.out.println(SomeClass.REF);
System.out.println(SomeClass.REF.message);
}
}
This would print out:
null
null
SomeClass@... // Object.toString() call
bla!
But there is absolutely no benefit to gain from using such an awful technique and tons of drawbacks.
Upvotes: 2