Kotlin - 可空场的非空吸气剂

awf*_*fun 6 java getter nullpointerexception non-nullable kotlin

我是Kotlin的新手,我尝试将一个小型Java项目改造成这种新语言.我在我的项目中使用mongodb,我有一个类,例如:

class PlayerEntity {

  constructor() {} //for mongodb to create an instance

  constructor(id: ObjectId, name: String) { //used in code
    this.id = id
    this.name = name
  }

  @org.mongodb.morphia.annotations.Id
  var id: ObjectId? = null

  var name: String? = null
}
Run Code Online (Sandbox Code Playgroud)

由于空构造函数,我必须将id字段标记为nullable(var id: ObjectId?).当我尝试从另一个类访问此字段时,我必须使用非null检查:thePlayer.id!!.但我的应用程序的逻辑是该id字段永远不为null(mongo创建一个Player实例并立即设置id字段).而且我不想在任何地方进行非空检查.

我试图创建一个非null的getter,但它不能编译:

var id: ObjectId? = null
    get(): ObjectId = id!!
Run Code Online (Sandbox Code Playgroud)

我也可以为id创建一些存根,并在构造函数中使用它,但这看起来像一个肮脏的黑客:

val DUMMY_ID = new ObjectId("000000000000000000000000");
Run Code Online (Sandbox Code Playgroud)

那么有解决问题的解决方法吗?

F. *_*rge 5

我个人在类似情况下使用以 + public val 为前缀的私有 var _

class Example<out T> {
  private var _id: T? = null
  val id: T
    get() = _id!!
}
Run Code Online (Sandbox Code Playgroud)

对于您的情况,它看起来像这样:

@org.mongodb.morphia.annotations.Id
private var _id: ObjectId? = null
val id: ObjectId
  get() = _id!!
Run Code Online (Sandbox Code Playgroud)

或者,lateinit像这样声明您的变量(但请注意,这公开了设置器):

@org.mongodb.morphia.annotations.Id
lateinit var id: ObjectId
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,“lateinit”是正确的做法;无需为第二处房产而烦恼。 (4认同)
  • getter/setter 无法覆盖其父 var/val 的类型,因此使用该 getter 的任何人仍必须对返回值进行非空断言 (`!!`)。 (4认同)
  • @yole 每个人都是他自己的,出于某种原因,我个人不喜欢“lateinit”。 (2认同)