An enumeration that is not part of the Enum?
The getDeclaringClass()
class method Enum
looks first if the enumeration value is the enumeration value, i.e. it's super Enum
. If not, return to the superclass of the class in which this instance was born, do the following:
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
How can the instance that runs the method getDeclaringClass()
NOT be a instanceof
class Enum
? The enum type cannot be extended, so the only superclass of the enum class is Enum
.
So - in the following example:
public enum Dirs {
NORTH, SOUTH, EAST, WEST
}
Dirs
is a subclass Enum
. However, Dirs
it cannot have a subclass itself, it cannot be extended.
getDeclaringClass()
any of the four directions - for example NORTH.getDeclaringClass()
- Dirs
that NORTH.getClass()
.
The source code getDeclaringClass()
suggests that there might be cases where it NORTH
might have a superclass other than Enum
. I don't understand how this can happen.
What am I missing?
EDIT:
In particular: how could there be a case where NOTNORTH.getDeclaringClass()
will return which is .NORTH.getClass()
Dirs
It is not entirely true that you cannot extend your own enum class. For example, in the case
enum Dirs {
NORTH {
@Override
public Dirs getOppositeDirection() {
return SOUTH;
}
},
SOUTH {
@Override
public Dirs getOppositeDirection() {
return NORTH;
}
};
public abstract Dirs getOppositeDirection();
}
Dirs
- it is really a class abstract
, and its enum values NORTH
and SOUTH
are implementations of this class, which provides an abstract method body getOppositeDirection
, which means that they are expanding Dirs
.
So if you call
System.out.println(Dirs.NORTH.getDeclaringClass());
System.out.println(Dirs.SOUTH.getDeclaringClass());
System.out.println(Dirs.NORTH.getClass());
System.out.println(Dirs.SOUTH.getClass());
In the output you will see something like
class yourPackage.Dirs
class yourPackage.Dirs
class yourPackage.Dirs$1
class yourPackage.Dirs$2
which means it getClass
will return a valid class that implements this enum, while it getDeclaringClass
will return the enum itself.
BTW: Enum doesn't have to be abstract in order to provide you with a concrete implementation of some method by accepting the enum extension. You can also do something like
enum MyEnum {
FOO {
@Override
public String toString() {
return "Foo";
}
},
BAR{
public String toString() {
return "baR";
}
};
}
and BAR.getDeclaringClass()
will return MyEnum
, and the result BAR.getClass()
will be MyEnum$2
.
Note that your enum has behavior, then each instance can have its own implementation.
public enum Dirs {
NORTH {
public Point move(Point p) { return p.move(0, 1); }
},
SOUTH {
public Point move(Point p) { return p.move(0, -1); }
},
EAST {
public Point move(Point p) { return p.move(1, 0); }
},
WEST {
public Point move(Point p) { return p.move(-1, 0); }
}
public abstract Point move(Point p);
}
class Point{
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public Point move(int dx, int dy) { return new Point(x + dx, y + dy); }
}
Now
assert Dirs.NORTH.getClass() != Dirs.SOUTH.getClass();
and
assert Dirs.NORTH.getDeclaringClass() == Dirs.SOUTH.getDeclaringClass();
Hope it helps.