简体   繁体   English

Java:如何创建通用的ENUM类型

[英]Java: How to create a generic ENUM Type

I am designing a web page that adds a variable and type of variable could be of form Double , String , ... The user will have to choose one of these types. 我正在设计一个添加变量的网页,变量的类型可以为DoubleString ,...形式。用户将不得不选择这些类型之一。 The backend will create variables based on the type defined by user. 后端将根据用户定义的类型创建变量。

I was thinking to have generic enum which can solve this. 我当时在想有可以解决此问题的通用枚举。 Like; 喜欢;

public enum VariableType<Type> {
    Double("Double", Double);
    String("String", String);

    private String name;
    private Type type;
}  

such that a on page load a REST call /variable/types returns list of types from enum and populate the dropdown list. 这样一来,页面加载REST调用/variable/types types就会从枚举中返回/variable/types列表,并填充下拉列表。

When user submits form based on the string passed a Type is associated. 当用户基于传递的字符串提交表单时,将关联一个Type

Seems like what I am doing is invalid, so I am looking for better ways to do this, please advice 看来我在做的事情是无效的,所以我正在寻找更好的方法来做,请咨询

Before starting my answer, I would like to say that an enum is an enumeration, that is a finite collections of named something. 在开始回答之前,我想说一个枚举是一个枚举,它是命名事物的有限集合。

That something are static final objects. 那是静态的最终对象。 So 所以

enum MyEnum {A,B,C;}

under the hood is something like: 在引擎盖下是这样的:

static final Object A = new MyEnum();
static final Object B = new MyEnum();
static final Object C = new MyEnum();

So, since I think you are not interested in having all possible types for your enum (at the end you have a fixed combo), I propose you a solution that tries to minimize effort and could be quite simple to implement once you have chosen the types you want to support. 因此,由于我认为您对拥有所有可能的枚举类型不感兴趣(最后您有了固定的组合),因此我为您提供了一种解决方案,该解决方案试图最大程度地减少工作量,并且一旦选择了即可实现。您要支持的类型。 In my solution, I chose Longs, Doubles, Points and Strings 在我的解决方案中,我选择了Longs,Doubles,Points和Strings

I give you directly the code, if you think that this solution goes toward your needs, I will be happy to improve is as your comments and request. 我直接给您提供代码,如果您认为此解决方案符合您的需求,我将很乐意根据您的评论和要求进行改进。

// MyType.java
package stackoverflow.answers;

import java.awt.Point;

public enum MyType {
    LONG {
        @Override
        public Object validateValue(Object o) {
            return (o instanceof Long) ? o : null;
        }

        @Override
        public Object parse(String s) {
            try {
                return Long.valueOf(s);
            } catch (Exception e) {
                return null;
            }

        }
    },
    DOUBLE {
        @Override
        public Object validateValue(Object o) {
            return (o instanceof Double) ? o : null;
        }

        @Override
        public Object parse(String s) {
            try {
                return Double.valueOf(s);
            } catch (Exception e) {
                return null;
            }

        }
    },
    STRING {
        @Override
        public Object validateValue(Object o) {
            return (o instanceof String) ? o : null;
        }

        @Override
        public Object parse(String s) {
            // stupid method, but needed.
            return s;

        }
    },
    AWTPOINT {
        @Override
        public Object validateValue(Object o) {
            return (o instanceof Point) ? o : null;
        }

        @Override
        public Object parse(String s) {
            if (s == null)
                return null;
            String ss[] = s.split(",");
            if (ss.length != 2)
                return null;
            try {
                return new Point(Integer.valueOf(ss[0]), Integer.valueOf(ss[1]));
            } catch (Exception e) {
                return null;
            }

        }
    };

    public String toString(Object o) {
        return o.toString();
    }

    public abstract Object validateValue(Object o);

    public abstract Object parse(String s);
}

then: 然后:

// GenericObject.java
package stackoverflow.answers;

public class GenericObject {

    private MyType _type;
    private Object _obj;

    public GenericObject(MyType type) {
        _type = type;
    }

    public void setValue(Object obj) {
        _obj = _type.validateValue(obj);
    }

    public void valueOf(String s) {
        _obj = _type.parse(s);
    }

    public String toString() {
        return _type.toString(_obj);
    }

}

and a test class: 和一个测试类:

package stackoverflow.answers;

public class EnumTest {

    public static void main(String[] args) {
        GenericObject o1 = new GenericObject(MyType.LONG);
        o1.setValue(new Long(42));

        GenericObject o2 = new GenericObject(MyType.DOUBLE);
        o2.valueOf("3.14");

        GenericObject o3 = new GenericObject(MyType.AWTPOINT);
        o3.valueOf("4,-30");

        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o3);

    }

}

The idea is quite simple, every time you need to support a new type, add an enum element. 这个想法很简单,每当您需要支持一种新类型时,都添加一个enum元素。 Abstract methods will force you to implement all you need to store, validate and parse (save on db is the next?) your values. 抽象方法将迫使您实现所有需要存储,验证和解析的值(下一个是保存在db上)。 Every time you need a new function (yes, like save on db), add a new abstract method and you will be forced to implement it for every type you decided to support. 每当您需要一个新函数(是的,例如保存在db上)时,添加一个新的抽象方法,您将被迫为决定支持的每种类型实现它。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM