如何强制对象创建时调用Setter方法以触发编译时警告或异常?
解决方案
编译时强制检查(推荐)
用建造者模式可以在编译阶段就确保str属性被赋值,从根源避免遗漏初始化的问题,示例代码如下:
class A private constructor(val str: String) { // 类的业务逻辑实现 companion object { fun builder() = Builder() } class Builder { private var str: String? = null fun setStr(paramsString: String) = apply { this.str = paramsString } fun build(): A { requireNotNull(str) { "str属性必须通过setStr方法赋值" } return A(str!!) } } }
使用方式:
// 必须调用setStr,否则IDE会编译提示,调用build()时也会抛出异常 val a = A.builder().setStr("test").build()
这种方式的优势:
- IDE在编译阶段就会提醒你必须设置
str - 若遗漏调用
setStr,build()会抛出明确的运行时异常,便于排查
运行时检查(简易方案)
如果不想引入建造者,也可以通过内部检查机制,在使用属性时强制校验初始化状态:
class A() { private var str: String? = null fun setStr(paramsString: String) { str = paramsString } // 对外提供获取str的方法,而非直接暴露属性 fun getStr(): String { return str ?: throw IllegalStateException("请先调用setStr初始化str属性") } // 类内部使用str前也需要做校验 fun doBusinessLogic() { val currentStr = getStr() // 业务逻辑代码 } }
使用示例:
val a = A() // a.getStr() // 直接调用会抛出异常 a.setStr("test") a.getStr() // 正常获取值
也可以结合lateinit做初始化检查:
class A() { lateinit var str: String fun setStr(paramsString: String) { str = paramsString } fun doBusinessLogic() { require(::str.isInitialized) { "请先调用setStr初始化str属性" } // 使用str做业务操作 } }
为什么你的尝试不生效?
你之前在init块中写setStr(strValue: String)是语法错误,init块无法直接接收外部参数,而且这种写法也无法强制外部调用者传入值。另外lateinit的特性是延迟初始化,只有在首次访问未初始化的lateinit属性时才会抛出异常,而非创建对象时。
内容的提问来源于stack exchange,提问作者avishak chakroborty
相关产品推荐
相关产品推荐

