我试图创建一个Box<T>类.它应该有两个公共不可变(val)属性,isContentMandatory: Booleancontent: T?.这是我想要接受的值的组合:

isContentMandatory content Should allow?
false null YES
false non-null YES
true null NO
true non-null YES

我想确保我提供的构造函数不会允许对象的非法状态.此外,我需要多个构造函数(或使用默认值),以便为客户端创建一个对象是straight-forward.以下是实例化示例:

Box()                        // OK -> isContentMandatory = false, content = null
Box("some-content")          // OK -> isContentMandatory = false, content = "some-content"
Box(false, "some-content")   // OK -> isContentMandatory = false, content = "some-content"
Box(true, "some-content")    // OK -> isContentMandatory = true, content = "some-content"
Box(true, null)              // DON'T ALLOW
Box(true)                    // DON'T ALLOW

如果可能的话,最好在编译时禁止使用上面的DON'T ALLOW(没有用于该组合的构造函数).否则,在创建过程中异常失败.

我来自Java世界,所以所有这些主要/次要构造函数、默认值等都有点模糊,所以请解释一下并给出解决方案.如果不同的类设计支持相同的业务逻辑,我也会接受.

EDIT:这就是它在Java中的外观.

public class Box<T> {

    private final boolean isContentMandatory;
    private final T content;

    public Box() {
        this(null);
    }

    public Box(T content) {
        this(false, content);
    }
    
    public Box(boolean isContentMandatory, T content) {
        if (isContentMandatory && content == null) {
            throw new IllegalArgumentException("Invalid combination of parameters");
        }
        this.isContentMandatory = isContentMandatory;
        this.content = content;
    }

    ...getters...
}

推荐答案

如果没有用例的实际领域知识,很难回答这是否是一种解决问题的好方法,但我觉得,用一个类来建模那些携带了一个(否则没有意义?)布尔值来分隔 case .

你可以有两个带有OptionalContent的盒子<;T&燃气轮机;和带有内容的盒子<;T>;对于这两种afaict,您只需要默认构造函数.

sealed interface Box<T: Any?> {
    abstract val content: T?
}
data class BoxWithContent<T: Any>(override val content: T): Box<T>
data class BoxWithOptionalContent<T: Any?>(override val content: T? = null): Box<T?>

这在初始化站点上不会有太大变化,在使用方面,您可能需要添加一个case语句来决定它是哪种情况,并进行适当的处理.但无论如何,您可能已经有了一些类似的逻辑,这可能会更加类型安全和可读.

Kotlin相关问答推荐

调用即发即忘方法--哪个作用域?

如何接受任何派生类KClass

Spring Boot kotlin协程不能并行运行

有没有一种简单的方法来识别物体?

Kotlin-elvis算子don';不使用map.get()

为什么我的通用Kotlin函数中的这个转换未经判断?

Kotlin 接口类型参数

Lets plot Kotlin中的多轴比例

如何在 Kotlin 中不受约束?

is return inside function definition 也是 kotlin 中的表达式

如何在 kotlin 中通过反射设置委托属性值?

Saripaar formvalidation 在 kotlin 中第二次不起作用

Kotlin 中的数据类

调用单元测试验证伴随对象方法

(kotlin的Moshi)@Json vs@field:Json

修改扩展函数中的this

Kotlin lambda 语法混淆

在多平台子元素中使用kapt

如何在 firebase 数据库中使用 kotlin 协程

Android room DAO 接口不适用于继承