如何在 Kotlin 类中声明一个公共值 (val) 以便稍后对其进行初始化。在这种特殊情况下不能使用 var

Posted

技术标签:

【中文标题】如何在 Kotlin 类中声明一个公共值 (val) 以便稍后对其进行初始化。在这种特殊情况下不能使用 var【英文标题】:How to declare a public value (val) in a Kotlin class to initialize it later. Cannot use var in this particular case 【发布时间】:2020-05-09 10:51:01 【问题描述】:

我正在尝试使用 Kotlin 在 android 上制作一个简单的相机应用。我无法将一些 java 代码转换为 Kotlin。 如何在 Kotlin 中声明 cameraDevice

Java 代码:

class MainActivity extends AppCompatActivity
protected CameraDevice cameraDevice;
    private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() 
        @Override
        public void onOpened(CameraDevice camera) 
            //This is called when the camera is open
            cameraDevice = camera;
            randomFunction();
        
        @Override
        public void onDisconnected(CameraDevice camera) 
            cameraDevice.close();
        
        @Override
        public void onError(CameraDevice camera, int error) 
            cameraDevice.close();
             cameraDevice = null;
        
    ;

Kotlin 代码:

class MainActivity : AppCompatActivity()
    val cameraDevice:CameraDevice?;
    private val stateCallback: CameraDevice.StateCallback = object : CameraDevice.StateCallback() 
        override fun onOpened(camera: CameraDevice) 
            //This is called when the camera is open
            cameraDevice = camera;
            randomFunction();
        
        override fun onDisconnected(camera: CameraDevice) 
            cameraDevice.close();
        
        override fun onError(camera: CameraDevice, error:Int) 
            cameraDevice.close();
            cameraDevice = null;
        
    ;

我无法将其定义为 var,它正在抛出 CameraDevice 类型的可空接收器上只允许安全 (?.) 或非空断言 (!!.) 调用?时间> 而且我无法在函数中声明它,会引发相同的错误。

【问题讨论】:

使用var cameraDevice:CameraDevice? = null 并像cameraDevice?.close() 一样使用它。如果你使用 val 那么你不能像cameraDevice = camera 那样重新分配它 你能解释一下为什么不把它声明为var吗? 【参考方案1】:

您应该像这样使用lateinit 代替cameraDevice

lateinit var cameraDevice: CameraDevice

如果遇到onError,请检查cameraDevice 是否已初始化,然后才调用close() 以避免得到UninitializedPropertyAccessException

@Override
public void onError(CameraDevice camera, int error) 
    if(::cameraDevice.isInitialized) 
        cameraDevice.close();
    

【讨论】:

【参考方案2】:

cameraDevice 可以随时为空。因此,您必须断言 not null 才能执行您的代码。但请确保 cameraDevice 在这里永远不会为空。 所以,使用你的代码如下

@Override
        public void onOpened(CameraDevice camera) 
            //This is called when the camera is open
            cameraDevice!! = camera;
            randomFunction();
        

在您的代码中随处使用它。

【讨论】:

这并没有真正告诉 OP 如何在他们声明它的地方初始化它 你错过了val cameraDevice:CameraDevice? = null【参考方案3】:

当你这样做时

     val cameraDevice:CameraDevice?;

val 变量需要初始 initialization 表示您在声明时已赋值 在initialization 变量之后,您无法更改它的值。

如果你想延迟初始化,那么你可以这样做

  var  cameraDevice:CameraDevice?=null // you have to assign the null at initial 

或者你可以像这样使用lateinit

  lateinit var cameraDevice:CameraDevice  //this does not required initialization at initial level

【讨论】:

我也想到了lateinit,但这只有在变量 WAS 在onOpened 中初始化时才有效。如果它只进入onError,它会崩溃。

以上是关于如何在 Kotlin 类中声明一个公共值 (val) 以便稍后对其进行初始化。在这种特殊情况下不能使用 var的主要内容,如果未能解决你的问题,请参考以下文章

kotlin 变量声明

Kotlin属性

如何在 ES6 类中声明公共函数?

Kotlin 什么是幕后字段?

Kotlin 变量和常量的声明(var和val)

kotlin 函数怎么返回多个值