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

+3


source to share


2 answers


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

.

+4


source


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.

+1


source







All Articles