0

I have this kind of enum

   public enum MyEnum {
        member1(MyClass1.class){
            @Override
            public void doStuff(Object obj) {
                ...
            }
        },
        member2(MyClass2.class){
            @Override
            public void doStuff(Object obj) {
                ...
            }
        };
        ...
        public abstract void doStuff(Object obj);
    }

What I would like to do is call the method in the enum like this:

MyEnum.member1.doStuff(myObject);

And have the methods in enum which object it has to cast to. Lets say the myObject that I pass in is MyClass1. The member1 should know automatically that it is only expecting MyClass1 which is also defined in the enum member description.

Is something like this even possible or I am walking a completely wrong path?

1
  • 3
    Completely the wrong path. Sorry. Start at the beginning, as explain what it is you are trying to do, not how you are trying to do it... Commented Apr 12, 2016 at 14:38

3 Answers 3

3
public enum MyEnum {
   member1(String.class){
      @Override
      public void doStuff(Object obj) {
         this.checkArgumentType(obj);
         String stringObj = (String) obj;
         //...
      }
   },
   member2(Integer.class){
      @Override
      public void doStuff(Object obj) {
         this.checkArgumentType(obj);
         Integer stringObj = (Integer) obj;
         //...
      }

   };

   private final Class<?> clazz;

   MyEnum(Class<?> clazz) {
      this.clazz = clazz;
   }

   void checkArgumentType(Object obj) {
      if (!clazz.isAssignableFrom(obj.getClass())) {
         throw new IllegalArgumentException("Wrong class");
      }
   }

   //...
   public abstract void doStuff(Object obj);
}
Sign up to request clarification or add additional context in comments.

3 Comments

I like this. Thank you! The seconds answer was also interesting but it indeed gets a bit too crazy really fast.
Note that this is not type-safe. You won't get an error at compile time when you pass the wrong type of object - you'll get an exception at runtime instead. In general it's better to catch errors at compile time instead of at runtime.
Well, it is type-safe. It is just not compile-time type-safe.
2

Something similar is possible, but it gets messy and complex real quick, up to the point where you should think about creating separate classes. But as an example, what you could do:

public enum Foo {

    member1(new Bar<String, Long>(Long.class){

        @Override
        void doStuff(String aString) {

        }

    });

    private final Bar<?,?> bar;

    private Foo(Bar<?,?> bar) {
        this.bar = bar;
    }

    private static abstract class Bar<A,B> {

        private final Class<B> type;

        Bar(Class<B> type) {
            this.type = type;
        }

        abstract void doStuff(A a);
    }
}

1 Comment

Nice solution, though indeed a bit from behind, through the chest in the eye. :-D
0

This is not possible with an enum in the way that you have it in mind.

Ideally you want to have compile-time type safety. Passing Object and then casting is not type-safe; nothing prevents you from passing a wrong kind of object, and you won't know it until runtime, when you get a ClassCastException when you try to cast the object to something that it's not.

Enums cannot have type parameters, so you cannot do anything with type parameters, like this:

// This is not valid Java!
public enum MyEnum<T> {
    member1<MyClass> {
        @Override
        public void doStuff(MyClass obj) { ... }
    }

    // ...
    public abstract void doStuff(T obj);
}

If you want type-safety, just use a bunch of constants instead of an enum:

interface MyConstant<T> {
    void doStuff(T obj);
}

public final class MyConstants {

    public static final MyConstant<MyClass1> MEMBER_1 = new MyConstant<MyClass1>() {
        @Override
        public void doStuff(MyClass1 obj) {
            // ...
        }
    };

    // etc.

    private MyConstants() {
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.