有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在一个对象中只允许一个非空字段的好方法是什么

我想编写一个包含1个以上不同类型字段的类,但在任何时候,实例对象中只有一个字段具有非空值

到目前为止,我所做的看起来并不干净

class ExclusiveField {

    private BigInteger numericParam;
    private String stringParam;
    private LocalDateTime dateParam;

    public void setNumericParam(BigInteger numericParam) {
        unsetAll();
        this.numericParam = Objects.requireNonNull(numericParam);
    }

    public void setStringParam(String stringParam) {
        unsetAll();
        this.stringParam = Objects.requireNonNull(stringParam);
    }

    public void setDateParam(LocalDateTime dateParam) {
        unsetAll();
        this.dateParam = Objects.requireNonNull(dateParam);
    }

    private void unsetAll() {
        this.numericParam = null;
        this.stringParam = null;
        this.dateParam = null;
    }
}

Java是以某种方式支持这种模式,还是有更合适的方式支持这种模式


共 (3) 个答案

  1. # 1 楼答案

    你可以使用反射。两个功能完成了。添加一个新字段?没问题。你甚至不需要改变任何事情

    public void SetExclusiveValue(String param, Object val){
        this.UnsetAll();
        Class cls = this.getClass();
        Field fld = cls.getDeclaredField(param); //Maybe need to set accessibility temporarily? Or some other kind of check.
        //Also need to add check for fld existence!
        fld.set(this, Objects.requireNonNull(val));
    }
    
    private void UnsetAll(){
        Class cls = this.getClass();
        Field[] flds = cls.getDeclaredFields();
        for (Field fld : flds){
            fld.set(this,null);
        }
    }
    

    如果可访问性是一个问题,您可以简单地添加一个可访问字段的列表,并对照该列表检查param

  2. # 2 楼答案

    unsetAll方法更改为setAll

    private void setAll(BigInteger numericParam, String stringParam, LocalDateTime dateParam) {
        this.numericParam = numericParam;
        this.stringParam = stringParam;
        this.dateParam = dateParam;
    }
    

    然后从公共设置器调用,如:

    public void setNumericParam(BigInteger numericParam) {
        setAll(Objects.requireNonNull(numericParam), null, null);
    }
    

    请注意Objects.requireNonNull是在setAll之前计算的,因此,如果要传入null{},这将在不更改任何内部状态的情况下失败

  3. # 3 楼答案

    为什么不简单

    public void setNumericParam(BigInteger numericParam) { 
         this.numericParam = Objects.requireNonNull(numericParam); 
         this.stringParam = null; 
         this.dateParam = null; 
    }