Kotlin null来自Java

当我将Java代码从一个库转换为Kotlin时,我会看到Java代码中是否存在空值检查,并想知道如何最好地将其转换。

我仍然需要在Kotlin的空检查,因为我不能控制,如果Java将使对象为空?

比方说,我有一个CameraDevice可以从Java返回null

我应该如何定义这个

private lateinit var mCameraDevice: CameraDevice 

然后不需要空检查或像这样..

 private var mCameraDevice: CameraDevice? = null 

然后保持空的检查

 if (mCameraDevice != null) { // do something } 

Kotlin的可玩性让我感到困惑,因为我觉得我不应该处理null,并且应该使用选项1,但是基本上我使用的每个库都是Java,所以我必须处理空值,并使用选项2

如果您不确定,则应该更好地使用可空类型,因为传统Java代码始终可能返回null 。 这个版本是最安全的。 否则,你知道null是不可能的,使用非空类型。

正如在文档中写的:

Java中的任何引用都可能为空,这使得Kotlin对来自Java的对象的严格无效安全的要求是不切实际的。 Java声明的类型在Kotlin中被专门处理,并被称为平台类型。 这种类型的空检查是放松的,所以它们的安全保证和Java一样。

如果您使用Java返回的值(您认为它们永远不会为null),将在运行时导致NullpointerException ,如果将它们作为不可空类型使用它们。

Java的:

 public class Nullable { public String get(){ return null; } } 

科特林:

 Nullable().get().length //-> NPE 

试试这个mCameraDevice?.yourMethod()

如果mCameraDevice不为null,它将执行你的方法。

ref: https : //kotlinlang.org/docs/reference/null-safety.html#safe-calls

 if (mCameraDevice != null) { // do something } 

else情况下你打算做else ? 如果答案是“抛出异常”,只需使用非空值类型,Kotlin会为您做好有效的处理; 否则可空类型是合理的。

此外,如果mCameraDevice是一个var ,在里面// do something Kotlin不能认为它是非null :检查之后可能会改变它! 一个常见的成语是

 mCameraDevice?.let { mCameraDevice -> // do something } 

lateinit是真的意味着什么是你听起来像变量,你最初初始化。

例如,在android中,您没有对构造函数进行评估,所以lateinit会派上用场,因为您在onCreate中设置了它的值,并且没有任何空的检查,所以您知道这个变量不是null ?!! 的。

例如:

 class MainActivity : AppCompatActivity() { private lateinit var field: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) field = findViewById<EditText>(R.id.field) } fun someOtherMethod() { println(field.text) } } 

没有lateinit你需要将field声明为EditText? 然后使用Kotlin提供的所有无效安全选项。

在Java interop中,如果一个库方法可以返回一个null,那么你应该把它当作一个Kotlin可为空,并通过保存导航来访问someObject?.someMethod或者其他一些安全的方式,比如let方法。

 someObject?.let { it.someMethod } // as also pointed out by Alexey Romanov 

所以在你的情况下,因为你明确地说Java可能会提供一个null CameraDevice ,你绝对应该使用lateinit,因为它不是预期的目的。