开发者

Enum and Generic constant specific method

开发者 https://www.devze.com 2023-01-20 17:00 出处:网络
I have an enum like: enum TEST { TEST1, TEST 2; public abstract <T> String stringify (T input); 开发者_StackOverflow中文版}

I have an enum like:

    enum TEST {
        TEST1, TEST 2;

        public abstract <T> String stringify (T input);
开发者_StackOverflow中文版    }

I need to add a constant specific method , something like stringify.

This method will take different types of inputs (for each enum). Can I do that? Eclipse is not letting me do it ..something like:

enum TEST {
    TEST1(
       public <Float> String stringify (Float input){
          return String.valueOf(input);
        }
    )
}


You can't do it with enums, but you can simulate this behaviour with generic class:

public abstract class TEST<T> {
    public static final TEST<Float> TEST1 = new TEST<Float>() {
        public String stringify (Float input){   
            return String.valueOf(input);   
        }
    };

    public abstract <T> String stringify(T input);
}


you can do it. but it's not clear what the benefit is:

enum TEST {
    TEST1 {
        public <Float>String stringify(Float input) {
            System.out.println("TEST1");
            return String.valueOf(input);
        }
    },
    TEST2 {
        public <Integer>String stringify(Integer input) {
            System.out.println("TEST2");
            return String.valueOf(input);
        }
    },
    TEST3 {};
    public <T>String stringify(T input) {
        System.out.println("super");
        return "";
    }
    public <Integer>String stringify2(Object input) {
        System.out.println("non generic");
        return String.valueOf(input);
    }
}
public class Main{
    public static void main(String[] args) {
        for(TEST test:TEST.values()) {
            System.out.println(test.stringify(new Float(1.23)));
            System.out.println(test.stringify(new Integer(42)));
            System.out.println(test.stringify(new Double(4.56)));
        }
        for(TEST test:TEST.values()) {
            System.out.println(test.stringify2(new Float(1.23)));
            System.out.println(test.stringify2(new Integer(42)));
            System.out.println(test.stringify2(new Double(4.56)));
        }
    }
}


Think of each Enum value as a class. So yes, the enums can have methods, just like a class does -- they all have the same methods though.

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

Look at the Planet example.

Also note that the enum itself can have static methods....(just like a class)


No, you can't make each enum constant implement an abstract method but require a different type of input than the other enum constants. If you could, what would happen if you were given an instance of your TEST enum (you don't know what constant it is) and tried to call stringify on it? What type would you pass it?

Edit: Given what you've said about these enums being used to decode strings into objects, it seems to me you have several options:

  • You could get a String representation of each decoded object by just calling toString() on it.
  • You could add a set of overloaded static method on the enum class itself, called stringify(Float) and stringify(Double), etc. Then you could just call TEST.stringify(value) and if there were a stringify method for the value's type, it'd work fine.

I imagine there are other options as well.


You can't use generics with enums, because the enum constants themselves are already the concrete (singleton) instances. At instance level, the generics must already be concrete.
So, I would stringly recommend going with one of the alternatives given in the other answers.

If you must do it in an enum, you could consider the following, which at least gives you a runtime means of type checking, including ClassCastExceptions. You won't have any support from the compiler though.

public enum TestEnum {
    Test1(Float.class),
    Test2(Integer.class),
    Test3(String.class);

    private final Class<?> iInputType;

    private TestEnum(final Class<?> pInputType) {
        iInputType = pInputType;
    }

    public Class<?> getInputType() {
        return iInputType;
    }

    public String stringify(final Object pInput) {
        return String.valueOf(iInputType.cast(pInput));
    }
}

Test Code:

System.out.println(TestEnum.Test1.stringify(1.23f));
System.out.println(TestEnum.Test2.stringify(42));
System.out.println(TestEnum.Test3.stringify("foo"));
// but:
// System.out.println(TestEnum.Test1.stringify("foo")); // -> ClassCastException!

for (TestEnum test : TestEnum.values()) {
    for (Object input : new Object[]{1.23f, 42, "foo"}) {
        if (test.getInputType().isAssignableFrom(input.getClass())) {
            System.out.println(test.stringify(input));
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号