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
source to share
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
.
source to share
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.
source to share