如何在Kotlin次级构造器中避免重复调用UUID.fromString?
避免Kotlin数据类次构造函数中重复调用UUID.fromString(id)的方案
原代码里的次构造函数为生成uuidId和stringId两次调用UUID.fromString(id),完全可以优化避免重复执行。
推荐方案:用工厂方法替代次构造函数
Kotlin的次构造函数要求必须直接调用主构造,没法在调用前先计算临时变量,所以改用伴生对象的工厂方法是最简洁靠谱的解决方式:
import java.util.UUID data class Entity( val uuidId: UUID?, val stringId: String?, val stuff: String ) { companion object { // 工厂方法:一次性解析UUID,避免重复调用 fun create(id: String, stuff: String): Entity { val parsedUuid = try { UUID.fromString(id) } catch (_: IllegalArgumentException) { // 解析失败时返回null null } return Entity( uuidId = parsedUuid, stringId = if (parsedUuid != null) null else id, stuff = stuff ) } } } // 使用示例 val validUuidEntity = Entity.create("550e8400-e29b-41d4-a716-446655440000", "test content") val invalidUuidEntity = Entity.create("invalid-uuid-string", "test content")
这个方案里UUID.fromString(id)只执行一次,解析结果同时用来生成uuidId和stringId,彻底避免了重复计算。
若必须保留次构造函数的替代方案
如果一定要保留次构造函数,虽然没有优雅的原生方式,但可以借助线程局部存储临时缓存解析结果(不推荐,复杂度高):
import java.util.UUID import kotlin.concurrent.getOrSet data class Entity( val uuidId: UUID?, val stringId: String?, val stuff: String ) { constructor(id: String, stuff: String) : this( uuidId = run { val parsedUuid = try { UUID.fromString(id) } catch(_: IllegalArgumentException) { null } // 临时缓存解析结果到ThreadLocal ThreadLocal.withInitial<UUID?> { null }.set(parsedUuid) parsedUuid }, stringId = run { // 从ThreadLocal取缓存的结果 val parsedUuid = ThreadLocal.withInitial<UUID?> { null }.get() ThreadLocal.withInitial<UUID?> { null }.remove() // 用完清空,防止内存泄漏 if (parsedUuid != null) null else id }, stuff = stuff ) }
这种方式繁琐且容易出问题,远不如工厂方法简洁可靠。
内容的提问来源于stack exchange,提问作者Kurt
相关产品推荐
相关产品推荐

