我目前正在尝试将一个小型应用程序从java转换为kotlin,而不必重写所有内容,但是我遇到了泛型枚举的问题,因为kotlin并不支持枚举中的泛型。
我在java中有以下枚举:
public enum Property {
LAST_VIEW(0, 1, Integer.class),
MAXIMIZED(2, false, Boolean.class),
private final int id;
private final String defaultValue;
private final Class<?> datatype;
<T> Property(final int id, final T defaultValue, final Class<T> datatype) {
this.id = id;
this.defaultValue = defaultValue == null ? null : defaultValue.toString();
this.datatype = datatype;
}
}
我将它用于通用属性api,以验证我的默认值是否具有正确的类型,并进行一些运行时检查,以便在我犯错误时立即给出正确的反馈。
有没有在kotlin上做这样的课程,还是我应该考虑重构我的属性api?
答案 0 :(得分:3)
也许您可以为此考虑密封课程,而不是枚举?
sealed class Property<T>(val id: Int, val defaultValue: T, dataType: Class<T>)
object LastView : Property<Int>(0, 1, Int::class.java)
object Maximised : Property<Boolean>(2, false, Boolean::class.java)
在这种情况下,由于LastView
和Maximized
没有任何用户定义或可变状态,我将其定义为objects
。由于Property<T>
已被密封,因此无法创建其他实例。
答案 1 :(得分:0)
虽然Kotlin不允许构造函数拥有自己的类型参数,但Java中的此功能仅影响调用站点上构造函数参数的类型检查(枚举条目不保留类型安全性)。因此,通过声明一个辅助类泛型类并在辅助构造函数中接受它的实例,可以在Kotlin中实现类似的行为:
class TypedDefaultValue<T>(
val defaultValue: T,
val datatype: Class<T>
)
enum class Property(
val id: Int,
val defaultValue: Any,
val datatype: Class<out Any>
) {
LAST_VIEW(0, TypedDefaultValue(1, Int::class.java)), // calls the constructor below
MAXIMIZED(2, TypedDefaultValue(false, Boolean::class.java));
constructor(id: Int, typedDefaultValue: TypedDefaultValue<out Any>) :
this(id, typedDefaultValue.defaultValue, typedDefaultValue.datatype)
}
使用枚举代码中的Any?
和out Any?
来接受可以为空的值。