欢迎光临
我们一直在努力

上说下教,假如让你说下下去

例子

lateinit 是kotlin的关键字,和var一起使用,用来声明一个不可空的不用立刻赋值的变量。通常用法是:

private lateinit var mScore: TextViewfun init(view: View) { 美国高防vps mScore = view.findViewById(R.id.score)}fun updateScore(score: Int) { mScore.text = “分数为:$score”}

相对于val和var而言,有几个好处:

不用立刻赋值;跟 val 相比,可以反复赋值;跟延后赋值的 var 相比,使用时不用到处加 ? 或 !!。 Java实现

我们先将上面例子中的代码用java写下:

private TextView mScore; public void init(View view) { mScore = view.findViewById(id.score); } public final void updateScore(int score) { mScore.setText((CharSequence)(“分数为:” + score)); }

再通过 Android Studio 的 show kotlin bytecode 工具,将例子中的kotlin转化成 java ,会发现这个代码跟我们用java代码写的挺像的。

private TextView mScore; public final void init(@NotNull View view) { Intrinsics.checkParameterIsNotNull(view, “view”); View var10001 = view.findViewById(id.score); Intrinsics.checkExpressionValueIsNotNull(var10001, “view.findViewById(R.id.score)”); this.mScore = (TextView)var10001; } public final void updateScore(int score) { TextView var10000 = this.mScore; if (var10000 == null) { Intrinsics.throwUninitializedPropertyAccessException(“mScore”); } var10000.setText((CharSequence)(“分数为:” + score)); }

去掉烦人的Intrinsics 的 checkParameterIsNotNull 、checkExpressionValueIsNotNull、throwUninitializedPropertyAccessException,那就是完全一样了!
可以推断 lateinit var 是一个为了照顾我们java写法习惯而创建关键词。

深入一点

看下 kotlin 生成的 java updateScore()方法,在 mScore 变量使用前,会先检查下是否为空,如果为空,会抛出异常:UninitializedPropertyAccessException。

public static void throwUninitializedPropertyAccessException(String propertyName) { throwUninitializedProperty(“lateinit property ” + propertyName + ” has not been initialized”); }

这就是我们在使用lateinit时会遇到的:lateinit property *** has not been initialized 异常。
因此:在使用lateinit var声明的变量前,一定保证变量被初始化了!
那有没有能检测 lateinit var的变量是否被初始化的方法呢?
答案是有,那就是使用lateinit var 变量的 isInitialized 属性。

fun updateScore(score: Int) { if (::mScore.isInitialized) { mScore.text = “分数为:$score” } }

转化成java是:

public final void updateScore(int score) { if (((Test)this).mScore != null) { TextView var10000 = this.mScore; if (var10000 == null) { Intrinsics.throwUninitializedPropertyAccessException(“mScore”); } var10000.setText((CharSequence)(“分数为:” + score)); } }

可以看到isInitialized的实现其实是做了判空,如果不为空,才去使用。果然比较符合java的习惯。

建议

避免使用lateinit var。因为非常容易出现“lateinit property *** has not been initialized”的异常。如果到处使用isInitialized,又会让代码会变得冗余。推荐 val 和var 搞定一切哈。

57793411

赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。