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,因为它不是预期的目的。