Kotlin如何安全访问lateinit变量的实现

Kotlin设计之初就是不允许非null变量在声明期间不进行初始化的,为了解决这个问题,Kotlin lateinit 允许我们先声明一个变量,然后在程序执行周期的将来某个时候将其初始化,让编译检查时不会 因为属性变量未被初始化而报错。如果未初始化将导致以下异常:

kotlin.UninitializedPropertyAccessException: lateinit property mList has not been initialized

所以我们在 Kotlin 1.2及更高版本上,经常使用基于反射的API 快速检查lateinit属性是否已初始化。

private lateinit var mList: MutableList<String>

fun main(args: Array<String>) {
  if (::mList.isInitialized) {
    mList.add("")
  }
}

但如果我们在一个类中有一个lateinit属性,然后尝试在另一类中检查它是被初始化,如下所示:

class PreA{
  lateinit var mList: MutableList<String>
}

class PreB{
  val mPreA = PreA()
  fun print(){
    if (mPreA::mList.isInitialized){

    }
  }
}

会报错:

Kotlin: Backing field of 'var mList: MutableList<String>' is not accessible at this point

因为该反射API的限定,当然inner class 是被允许的,具体设计细节参考官方

所以我们如有类似需求可以直接在目标类中添加新方法来检查lateinit属性:

class PreA{
  lateinit var mList: MutableList<String>
  fun isListInitialised() = ::mList.isInitialized
}

class PreB{
  val mPreA = PreA()
  fun print(){
    if (mPreA.isListInitialised()){
      mPreA.mList.add("")
    }
  }
}

当然通过捕获UninitializedPropertyAccessException 异常也是可以

参考: StackOverflow

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Kotlin 匿名类实现接口和抽象类的区别详解

    我就废话不多说了,还是上代码吧 接口: interface OnBind { fun onBindChildViewData(holder: String, itemData: Any, position: Int) } lesson.does(object : OnBind { override fun onBindChildViewData(holder: String, itemData: Any, position: Int) { println(holder + itemData +

  • 解决Kotlin 类在实现多个接口,覆写多个接口中相同方法冲突的问题

    一.首先来看一个例子 package net.println.kotlin.chapter4 /** * @author:wangdong * @description:类实现接口的冲突问题 */ interface B{ fun x(): Int = 1 } interface C{ fun x(): Int = 0 } /**一个类实现了两个接口,两个接口中的方法相同,这个类在覆写的时候就会出现冲突*/ class D: B,C{ //当下面两个方法同时存在的时候,就会报方法相同的冲突 ov

  • Android中AndroidStudio&Kotlin安装到运行过程及常见问题汇总

    工具:Android Studio 语言:Kotlin 1.Android Studio的安装与配置 AndoridStudio官方网址:直接点击即可进入AS官网下载页面 1.1.android studio的下载与安装 下载好AS的文件后,直接打开androidstudio的exe文件,弹出安装欢迎对话框如下图所示 点击Next 勾选Android Virtual Devide(AVD)安卓虚拟设备,这样之后可以在电脑上生成一个虚拟的安卓机以方便我们运行编写好的程序.如果准备用真机进行测试的,

  • Kotlin 使用Lambda来设置回调的操作

    使用Kotlin的Lambda表达式,我们可以抛弃回调接口的使用.只需设置希望后面会被调用的函数即可. 示例如下 新建一个Kotlin类 class MyBean { fun testcallback1(callback: (String) -> Unit) { callback.invoke("这是回调的内容") } fun testcallback2(value1: Int, value2: Int, callback: (Int, Int) -> Int): Int

  • Kotlin如何安全访问lateinit变量的实现

    Kotlin设计之初就是不允许非null变量在声明期间不进行初始化的,为了解决这个问题,Kotlin lateinit 允许我们先声明一个变量,然后在程序执行周期的将来某个时候将其初始化,让编译检查时不会 因为属性变量未被初始化而报错.如果未初始化将导致以下异常: kotlin.UninitializedPropertyAccessException: lateinit property mList has not been initialized 所以我们在 Kotlin 1.2及更高版本上,

  • python访问系统环境变量的方法

    本文实例讲述了python访问系统环境变量的方法.分享给大家供大家参考.具体如下: #-------------------------------- # Name: enviroment_variables.py # Author: Kevin Harris # Last Modified: 02/13/04 # Description: This Python script demonstrates # how to acces enviroment variables. #--------

  • java使用反射访问成员变量的值示例

    本文实例讲述了java使用反射访问成员变量的值.分享给大家供大家参考,具体如下: 一 代码 import java.lang.reflect.*; class Person { private String name; private int age; public String toString() { return "Person[name:" + name + " , age:" + age + " ]"; } } public class

  • java 继承访问成员变量代码实例

    这篇文章主要介绍了java 继承访问成员变量代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package java09; //创建父类 public class Fu { int numFu = 10; int num =100; public void methodFu(){ System.out.println(num); } } package java09; //创建子类 public class Zi extends Fu

  • JavaScript中子函数访问外部变量的3种解决方法

    前言 我们在写web页面时,肯定会经常遇到下面这种情况: <body> <div class="btns-wrapper"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> var wrapper = $('.btns-wrapper'); fo

  • JavaScript闭包函数访问外部变量的方法

    闭包是指有权访问另一个函数作用域中的变量的函数,但作用域的配置机制有一个需要注意的地方,即闭包只能取得包含函数中任何变量的最后一个值. 如以下案例: function create(){     var arr = new Array();        for (var i=0; i<10; i++){         arr[i] = function(){             return i;         };      }       return arr; }   var c

  • 六、访问CGI变量

    6.1 CGI变量概述 如果你是从传统的CGI编程转而学习Java Servlet,或许已经习惯了"CGI变量"这一概念.CGI变量汇集了各种有关请求的信息: 部分来自HTTP请求命令和请求头,例如Content-Length头: 部分来自Socket本身,例如主机的名字和IP地址: 也有部分与服务器安装配置有关,例如URL到实际路径的映射. 6.2 标准CGI变量的Servlet等价表示 下表假定request对象是提供给doGet和doPost方法的HttpServletReque

  • java1.5中访问环境变量

    如: 复制代码 代码如下: public class EnvTest {   public static void main(String args[]) {     System.out.println(System.getenv(args[0]));   } } 运行结果: C:\java>java    EnvTest OS Windows_NT 又如: 复制代码 代码如下: import java.util.Map; public class EnvDump { public stati

  • Python中设置变量访问权限的方法

    在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name.score属性: >>> bart = Student('Bart Simpson', 98) >>> bart.score 98 >>> bart.score = 59 >>> bart.score 59 如果要让内部属性不被外部

  • Java的访问修饰符与变量的作用域讲解

    Java访问修饰符(访问控制符) Java 通过修饰符来控制类.属性和方法的访问权限和其他功能,通常放在语句的最前端.例如: public class className { // body of class } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments)

随机推荐