可以支持不同类型的Java类属性

可以支持不同类型的Java类属性,java,types,Java,Types,我正在用Java构建一个内容管理系统,我有一个类来表示一个实体,还有一个类来表示实体中的一个字段 当前我的字段类作为字符串数组列表来存储所有值 我的班级是这样的: public class Field implements Serializable { private UUID key; private String name; private ArrayList<String> values; private Integer maxValues;

我正在用Java构建一个内容管理系统,我有一个类来表示一个实体,还有一个类来表示实体中的一个字段

当前我的字段类作为字符串数组列表来存储所有值

我的班级是这样的:

public class Field implements Serializable {
    private UUID key;
    private String name;
    private ArrayList<String> values;
    private Integer maxValues;
    private ValueType type;
    private String code;

    public enum ValueType {
        INT,
        VARCHAR,
        DATE,
        BOOLEAN
    }

    public void addValue(String value){
        if (this.values.size() < this.maxValues){
            this.values.add(value);
        }
    }

    public ArrayList<String> getValues(){
        return this.values;
    }
}
公共类字段实现可序列化{
专用UUID密钥;
私有字符串名称;
私有数组列表值;
私有整数值;
私人价值型;
私有字符串码;
公共枚举值类型{
INT,
瓦查尔,
日期,
布尔值
}
公共void addValue(字符串值){
if(this.values.size()
我想存储字符串、整数、浮点数和日期,我想我可以在输入值时键入检查值,并使用单独的方法将值作为正确的类型

public ArrayList<Integer> getIntegerValues(){

    ArrayList<Integer> integerValues = new ArrayList<Integer>();


    values.forEach(
        (v) -> {

            Integer intValue = Integer.parseInt(v);

            integerValues.add(intValue);

        }
    );

    return integerValues;
}
public ArrayList getIntegerValues(){
ArrayList integerValues=新的ArrayList();
价值观(
(v) ->{
整数intValue=Integer.parseInt(v);
integerValues.add(intValue);
}
);
返回整数值;
}
我认为这会起作用,但感觉它不是一个很好的解决方案,因为当使用这个类时,您必须选择正确的函数来获取类型。如果只有一个函数返回正确的版本就好了


有人知道我该如何更好地写这篇文章吗。

下面是一个如何使用泛型的示例:

public class Field<T> implements Serializable {
    private UUID key;
    private String name;
    private ArrayList<T> values;
    private Integer maxValues;
    private String code;

    public void addValue(T value) {
        if (this.values.size() < this.maxValues){
            this.values.add(value);
        }
    }

    public ArrayList<T> getValues(){
        return this.values;
    }
}
公共类字段实现可序列化{
专用UUID密钥;
私有字符串名称;
私有数组列表值;
私有整数值;
私有字符串码;
公共无效附加值(T值){
if(this.values.size()
更多的是另一种观点:如果你认为泛型在这方面对你没有帮助,你仍然应该而不是对这类事情使用枚举

Enum的问题是:它们对于将来发生更改的可能性很小的“模型”非常有用。因为通常发生的情况是:对于您拥有的每个枚举,您将创建switch语句;以便为不同的枚举常量实现不同的行为。这听起来可能不是个问题,但它是。。。当您意识到需要添加另一个
类型时。然后,您必须找到所有这些开关,并决定如何处理新的枚举常量

相反,您的设计应该由以下因素驱动:保持开放以进行更改;但已关闭进行修改。在OO中,这通常转化为使用抽象类,如

public abstract class ValueType {
  ... which has some ABSTRACT methods
  ... and probably some FINAL methods
抽象方法是实现不同子类的行为的地方;最后的方法是那些“修复”该行为的方法,对于这个类的每个实例都应该是相同的

然后继续创建特定的子类,比如
IntValue扩展ValueType
等等


为什么这样更好?非常简单:添加一种新的ValueType意味着。。。创建一个新的子类-无需接触任何现有代码。因此,这样的设计是开放的用于更改(添加新类型!),而关闭的用于修改(因为添加新类型不会更改其他现有类中的任何内容)。

我对两种答案都不是100%满意,也不是解决此问题的正确方法,两种方法都有问题要处理。然而,我意识到这两个答案结合在一起会给出一个很好的解决方案,所以多亏了这两个答案

具体类将定义泛型值的值。这将满足开闭原则

public interface FieldType<T> {
    void addValue(T value);
    ArrayList<T> getValues();
}

public abstract class Field<T> implements FieldType<T>, Serializable {
    private UUID key;
    private String name;
    protected ArrayList<T> values;
    private Integer maxValues;
    private String code;

    public abstract void addValues();

    public ArrayList<T> getValues(){
        return this.values;
    }
}

public class FloatField extends Field<Float> {

    @Override
    public void addValue(Float value) {
        this.values.add(value);
    }

    @Override
    public ArrayList<Float> getValues() {
        return this.values;
    }
}
公共接口字段类型{
无效附加值(T值);
ArrayList getValues();
}
公共抽象类字段实现FieldType,可序列化{
专用UUID密钥;
私有字符串名称;
受保护的ArrayList值;
私有整数值;
私有字符串码;
公共摘要void addValues();
公共ArrayList getValues(){
返回这个值;
}
}
公共类FloatField扩展字段{
@凌驾
公共无效附加值(浮动值){
这个.values.add(值);
}
@凌驾
公共ArrayList getValues(){
返回这个值;
}
}

看起来您想使用Generics单个字段可以包含多个类型吗?不,字段永远不会包含不同的类型。我非常喜欢这个想法,可以强制在构造函数中添加ValueType,但是如果抽象方法addValue和getValue需要使用泛型?虽然我已经检查了泛型的答案是否正确,但我已经为泛型实现编写了代码,我发现它不是最佳解决方案,它违反了您提到的开闭原则,我认为Field类可能需要抽象,因此需要一个VarcharField/IntegerField/FloatField extends字段,将尝试实现,看看感觉如何,但在我看来,它将提供更大的设计灵活性,更容易添加新类型。我很高兴您发现我的输入很有帮助。如果可能的话,我建议你和一些有经验的人面对面交谈;这样的问题需要很多思考;交换想法通常会有所帮助。我喜欢这个想法,我认为它可以解决我的问题,但同时也会带来另一个问题,即在返回时不知道类型。我认为在向字段添加值以对应于对象类型时,我会执行严格的类型检查。您应该知道类型。当你定义一个Fi时