Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java advanced Enum with an abstract method and used for branching

Tags:

java

oop

enums

I'm new to java and came across some advanced Enum code in my organization. I am familiar with enums defined as follows: public enum someList { VALUE1, VALUE2, ..}

But in the advanced enum that I came across, a lot more seems to be going on..

/**
 * Defines ways to compare records in {@link ApplicationStatus} to see if they
 * are the same.
 */
public enum SourceStatusComparisonType
{
    CONTEXT_KEY
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getContextKey() == status.getSourceContextId();
        }
    },
    DATE
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getCobDate().equals(status.getCobDate());
        }
    };

    public abstract boolean compareKeys(SourceStatus source,
            ApplicationStatus status);
}

Could someone enlighten me on what's going on with the abstract method that's being overridden and overloaded. I don't understand what's going on in the above. I was told this is being used to abstract away if/else blocks from the code that uses it. But I'm not sure I understand.

Thank you in advance.

like image 535
Horse Voice Avatar asked Jan 12 '23 08:01

Horse Voice


2 Answers

Each enum constants can be optionally followed by a class body, as specified in JLS §8.9.

The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type. The class body is governed by the usual rules of anonymous classes; in particular it cannot contain any constructors.

So, it is like creating an abstract class SourceStatusComparisonType, with an abstract method - compareKeys(). You create 2 instances of that class:

CONTEXT_KEY = new SourceStatusComparisonType() {
        @Override
        public void compareKeys() { .. }
    };

DATE = new SourceStatusComparisonType() {
        @Override
        public void compareKeys() { .. }
    };

And override the abstract method for each instances. You can't have any instance, without having an implementation of that method.

Similarly, all the enum constants, must provide an implementation of the abstract method in it's respective anonymous class body. Else, you can't have that method as abstract. You have to provide a body, which will be used by default for the enum constants, that don't provide that method implementation:

public enum SourceStatusComparisonType
{
    CONTEXT_KEY
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getContextKey() == status.getSourceContextId();
        }
    },
    DATE
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getCobDate().equals(status.getCobDate());
        }
    },
    DEFAULT;

    public boolean compareKeys(SourceStatus source,
            ApplicationStatus status) {
//        return somedefaultvalue;
    }
}

So, for the first 2 constants, when you invoke compareKeys method, their specific implementation will be used, and for DEFAULT, the method defined outside will be used.

like image 122
Rohit Jain Avatar answered Jan 30 '23 13:01

Rohit Jain


Enum type can have body like abstract methods and all enum constants should implement those abstract methods.

Look at the JSL here http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2 and go to the section Example 8.9.2-4. Enum Constants with Class Bodies.

You even can implement an ENUM with an interface rather having a abstract method in it. Something like public enum SourceStatusComparisonType implements StatusComparable.

like image 24
RP- Avatar answered Jan 30 '23 13:01

RP-