当我将Java代码从库转换为Kotlin时,我会看到是否在Java代码中检查了null,并想知道如何最好地转换它。
我是否还需要Kotlin中的if null检查,因为我无法控制Java是否会使对象为空?
假设我有一个可以从Java返回null的CameraDevice
我应该像这样定义..
private lateinit var mCameraDevice: CameraDevice
然后不需要空检查或像这样..
private var mCameraDevice: CameraDevice? = null
然后保持空检查
if (mCameraDevice != null) { // do something }
Kotlin中的Nullability使我感到困惑,因为我觉得我不应该处理null并且应该使用选项1,但基本上我使用的每个库都是Java所以我必须处理空值并使用选项2
答案 0 :(得分:1)
如果您不确定,最好使用可空类型,因为遗留Java代码总是有可能返回null
。这个版本最安全。如果不知道null
是不可能的,请使用非可空类型。
正如docs所述:
Java中的任何引用都可能为null,这使得Kotlin对严格的null安全性的要求对来自Java的对象不切实际。 Java声明的类型在Kotlin中被特别处理并称为平台类型。对这些类型放宽空检查,因此对它们的安全保证与Java相同。
如果你使用Java返回的值,你认为永远不会为null,那么如果你使用它们作为非可空类型,它们将在运行时引起NullpointerException
。
<强>爪哇:强>
public class Nullable {
public String get(){
return null;
}
}
<强>科特林:强>
Nullable().get().length //-> NPE
答案 1 :(得分:1)
试试这个mCameraDevice?.yourMethod()
如果mCameraDevice
不为空,它将执行您的方法。
参考:https://kotlinlang.org/docs/reference/null-safety.html#safe-calls
答案 2 :(得分:1)
if (mCameraDevice != null) { // do something }
你在else
案件中打算做什么?如果答案是“抛出异常”,只需使用非可空类型,Kotlin将为您有效地执行此操作;否则可以为空的类型是合理的。
此外,如果mCameraDevice
是var
,则// do something
内部Kotlin不能认为它不是null
:检查后有些东西可能会改变它!一个常见的习语是
mCameraDevice?.let { mCameraDevice -> // do something }
答案 3 :(得分:0)
lateinit
真正意味着听起来像是你最近初始化的变量。
例如在android中你没有评估一个活动的构造函数,所以lateinit
派上用场,你想要访问一个你知道不是null的变量,因为你在onCreate中设置了它的值任何空检查,?
或!!
。
例如:
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提供的所有null安全选项。
在Java互操作中,如果库方法可以返回null,那么您应该将其视为Kotlin可空,并通过保存导航someObject?.someMethod
或其他安全方式(如let方法)进行访问。 / p>
someObject?.let { it.someMethod } // as also pointed out by Alexey Romanov
因此,在您的情况下,因为您明确说Java可能会为您提供null CameraDevice
,所以您绝对应该不使用lateinit,因为它不是预期目的。