I finally have a reason to implement an enum in Java and and find it to be an invalid type in 1.6. So I declare the enum as
public enum MyEnum = {A=0, B=1, C=3};
and get an error invalid type in Eclipse.
That's not how they are used. See examples at http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html, such as
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
Java enums are much more powerful than in, say, C#. They're (almost) full-blown objects, and thus cannot be represented with just a number. They can however contain a number, and they do have an ordinal number value.
You could have the number value with
public enum MyEnum {
A(0), B(1), C(3);
private final int number;
MyEnum(int number) {
this.number = number;
}
}
Java enums are quite different to C and C++ enums. The biggest difference is that the enum constants are full-blown objects rather than compile-time integer constants.
In your example, A, B and C are objects. Therefore constructs like A=0, B=1, C=3 are not allowed.
I recommend taking a look at the tutorial.
If you have to associate numeric values with enum constants, you can achieve a similar effect like so:
public enum MyEnum {
A(0), B(1), C(3);
public final int val;
private MyEnum(int val) {
this.val = val;
}
}
Having done this, you can access the values using MyEnum.A.val etc.
In Java, enum is a type, but it is incompatible with integers. Enum objects are closer to classes than to primitives, in that they can have methods, member variables, and so on.
Java lets you get the effect that you wanted by adding an int member to your enumeration, and initializing it differently for different enumeration members, like this:
public enum MyEnum {
A(1), B(2), C(3);
int val;
private MyEnum (int v) {
val = v;
}
public int value() {
return val;
}
};
Now each member of your enum has a public method value() that returns the integer value associated with the corresponding element of the enumeration.
you can't do this as you do. enum define in java in the following way
enum myenum{a,b,c,d}
public enum ModuleType {A,B,C}
To answer your question: enum is technically not a type. Therefore you cannot define a variable of type enum as you have tried.
enum is a keyword to define an enumerated (abbreviated to enum) type which is a special data type.
Once an enum type is defined (very much like how you would define a class), you refer to it using the name of the enum type. Please check the enum types documentation.
Related
If I were to declare an enum like so
public enum Foo {A, B, C}
then I can get the enum values using
Foo[] values = Foo.values();
However if I wanted to pass Foo as a generic type, like so, I can't get the values since it's generic.
class Bar<E extends Enum<E>> {
public Bar(E e) {
E[] values = e.values(); // not possible
}
}
Is it possible to iterate over the enum values any other way?
You'll have to pass the Class object:
public Bar(Class<E> clazz) {
E[] values = clazz.getEnumConstants();
}
...or, if you have one element e of the enum, you might be able to use e.getDeclaringClass().getEnumConstants(). (Don't use e.getClass().getEnumConstants(), which won't work if your enum constants define their own constant-specific methods.)
Another option: EnumSet.allOf(clazz), which is actually more efficient than clazz.getEnumConstants() in many ways, since it's O(1) and not O(n) in the number of enum constants.
What i mean by that is suppose
Enum xyzType {
A,
B,
C,
D
}
I know I can get the ordinal a value of C, by doing xyzType.C.ordinal() which is 2.
Suppose I just have 2, I would to get the enum type C. I can't seem to find anything in the enum API that would do this. I would prefer not to have a huge switch statement to compare each ordinal value and return the enum. Is there a better to do this ?
The simplest approach is:
xyzType xyz = xyzType.values()[ordinalValue];
However, this will create a new array each time. An alternative would be to cache it within the enum:
public enum Xyz {
Foo, Bar;
private static final Xyz[] VALUES = values();
public Xyz fromOrdinal(int ordinal) {
return VALUES[ordinal];
}
}
How can I cast a value from Enum1 to Enum 2 in Java?
Here is an example of what I'm trying to do :
public enum Enum1 {
ONE,
TWO,
THREE;
}
public enum Enum2 {
FOUR,
FIVE,
SIX;
}
So I want to do something like this:
Enum2 en2 = (Enum2)ONE;
Is it possible and how can I do that?
Thanks in advance!
You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another (preserving order). For example:
enum E1 {
ONE, TWO, THREE,
}
enum E2 {
ALPHA, BETA, GAMMA,
}
we can translate E1.TWO to/from E2.BETA by:
static E2 E1toE2(E1 value) {
return E2.values()[value.ordinal()];
}
static E1 E2toE1(E2 value) {
return E1.values()[value.ordinal()];
}
The answer depends on what the "casting" should do...
Casting by ordinal position
In the provided example, there is no commonality between the two sets of enum values so I'm assuming the intention was to translate by ordinal position so Enum1.ONE => Enum2.FOUR, Enum1.TWO => Enum2.FIVE and Enum1.THREE => Enum2.SIX. This can be done as follows:
Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];
A natural follow-on question is how this can be extended to a generic function that does the same for any two enum types. Not for the faint hearted but this does the job - it requires the Google Guava library:
public <F extends Enum<F>> F castByOrdinal(Enum<?> e, Class<F> fClass) {
return Iterators.get(EnumSet.allOf(fClass).iterator(), e.ordinal());
}
If Guava isn't being used, it can be done manually in a few more lines of code:
public <F extends Enum<F>> F castByOrdinal(final Enum<?> e, final Class<F> fClass){
final Iterator<F> iter = EnumSet.allOf(fClass).iterator();
int count = 0;
F fValue = null;
while (count <= e.ordinal()) {
if (!iter.hasNext()) {
return null; // ...Or throw an exception e.g. IndexOutOfBoundsException
}
fValue = iter.next();
count++;
}
return fValue;
}
Example usage:
Enum2 en2 = castByOrdinal(Enum1.ONE, Enum2.class);
Casting by shared enum value names
There is another possible way of casting between enums that share some of the same value names.
E.g:
enum Shape {
TRIANGLE, SQUARE, PENTAGON, HEXAGON, UNKNOWN, NOT_APPLICABLE
}
enum Size {
SMALL, MEDIUM, LARGE, UNKNOWN, NOT_APPLICABLE
}
The casting will only work for common values (i.e. UNKNOWN and NOT_APPLICABLE above) and can be done as follows:
Size size = Size.valueOf(Shape.UNKNOWN.name());
This will throw an IllegalArgumentException if the value name does not exist in the target enum. The generic method for this casting is a bit simpler:
public <F extends Enum<F>> F castByName(final Enum<?> e, final Class<F> fClass) {
return F.valueOf(fClass, e.name());
}
Example usage:
Size size = castByName(Shape.UNKNOWN, Size.class);
You can define a method in Enum1 to return the corresponding Enum2:
enum Enum1 {
ONE {
#Override
public Enum2 toEnum2() {
return Enum2.ALFA;
}
},
TWO {
#Override
public Enum2 toEnum2() {
return Enum2.BETA;
}
}
,
THREE {
#Override
public Enum2 toEnum2() {
return Enum2.GAMMA;
}
}
;
public abstract Enum2 toEnum2();
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
or, a bit more readable (IMO):
enum Enum1 {
ONE(Enum2.ALFA),
TWO(Enum2.BETA),
THREE(Enum2.GAMMA);
private final Enum2 enum2;
private Enum1(Enum2 enum2) {
this.enum2 = enum2;
}
public Enum2 toEnum2() {
return enum2;
}
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
EDIT:
if you need to maintain the 2 enums decoupled, create a map containing the mapping from Enum1 to Enum2 (in a 3rd utility class).
It's not possible. Enum1 and Enum2 are different types with nothing in common.
Even though this ticket was active quite a while ago I'm adding another possibility:
You could also create a Map e.g. like this:
HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);
usage
Enum2 e2 = e1ToE2.get(Enum1.ONE);
(+) you dont have to double check the order of your elements
(+) easy to read
(+) fast
(-) requires space
Correct me if I'm wrong :)
You can't do that, because they're objects of different classes.
You could convert from one to the other based on ordinal value or name, but I'd question the design of any program that needed to do that.
You can't ; but you can create a static method in your enums, with a translation code. But you must have a clear idea of the rules you want to implement.
A cast operation is not possible, but you can write a static member function for enum1 that casts enum2 to enum1:
public static Enum1 fromEnum2(Enum2 enum2) {
...
}
By the way, you can assign an ID to every constant of both enums which simplifies the implementation.
Here is a tutorial on enums.
It probably won't help you, but you can have
public enum Enum1 implements MyInterface {...}
public enum Enum2 implements MyInterface {...}
We don't have enough information about what you are trying to do to help you.
It makes no sense as it is to cast an enum to another enum.
You cannot cast from one enum to another, however each enum has guaranteed order, and you can easily translate one enum to another
Are there any objects created respective to each of the enum constants ARROGANT, RASCAL, IDIOT?
public enum Manager {
ARROGANT,
RASCAL,
IDIOT
}
and if the following code does the same as the above, explicitly though,
public enum Manager {
ARROGANT(),
RASCAL(),
IDIOT();
Manager() {}
}
Yes, exactly one instance will be created for each enum constant.
And yes, the second sample code is effectively identical.
Yes, both should result in the same bytecode, the first is only syntactic sugar.
The second is useful when you have to associate values with an enum.
enum Numbers{
ONE(1),TWO(2),THREE(3),TEN(10);
Numbers(int i){
value = i;
}
public final int value;
}
I am learning Enums in java I like to know what are the major differences of Enum in java and C++.
Thanks
In c++ an enum is just a list of integer values.
In java an enum is a class which extends Enum and is more a nice way to write:
class MyEnum extends Enum<MyEnum>
{
public final static MyEnum VE01 = new MyEnum();
public final static MyEnum VE02 = new MyEnum();
}
as enum:
enum MyEnum
{
VE01,VE02;
}
For the Methods of enum see this.
Since a java enum is an object it supports everything a normal java object does.
as giving them values or functions:
enum Binary{
ZERO(0),ONE(1);
Binary(int i)
{
value = i;
}
public final int value;
}
a nice one is anonymous classes:
enum State{
StateA{
public State doSomething()
{
//state code here
return StateB;
}
},
StateB{
public State doSomething()
{
return StateA;
}
};
public abstract State doSomething();
}
In C++, an enumeration is just a set of named, integral constants. In Java, an enumeration is more like a named instance of a class. You have the ability to customize the members available on the enumeration.
Also, C++ will implicitly convert enum values to their integral equivalent, whereas the conversion must be explicit in Java.
More information available on Wikipedia.
Enums in C/C++ are plain Integers.
Enums in Java are objects - they can have methods (with different behavior from one enum instance to the other). Moreoever, the enum class supplies methods which allows iteration over all enum instances and lookup of an enum instance.
C++:
typedef enum { Red, Yellow, Green } Colors;
void canCrossIntersection(Colors c) {
return c == Green;
}
Java:
public enum Colors {
RED(false),
Yellow(false),
Green(true)
;
Color(boolean b) { this.b = b; }
private boolean b;
public boolean canCrossIntersection() { return b; }
}
In Java you can even emulated extensible enums by letting them implement the same interface and then add all of their values to some sort of collection by calling their values() method.
For a semi-answer... C++0x Strongly Typed Enums bring many of the benefits of Java Enums to C++: strong typing, scope and so forth. If your compiler supports C++0x Strongly Typed Enums, you should consider using them.
Reference:
http://www2.research.att.com/~bs/C++0xFAQ.html#enum
A great feature of Java Enums which lacks in C++ is the name() method. This way you can get the Enum value name (as written in the enum definition) without any extra line of code in definition. For example:
enum Type {T1, T2, T3}
Type t = Type.T1;
System.out.println(t.name()); // prints T1