Kotlin的高级特性:7、不可变的变量并不是常量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/android_zyf/article/details/82691516

语法特性背后的知识

  • 变量、常量与只读
    • var:变量
    • val:不可变的变量,不是一个常量
  • 空安全是如何实现的
    • 对比 java 语言是如何实现 空检查的
  • 内联的特殊情况
  • Kotlin 的真泛型与实现方法

需要掌握的命令:javap [option] *.class
jdk 提供的反编译 class 文件的命令,可以很好的用来分析 Kotlin 的编译过程

子命令 输出信息
-l 输出行和变量的表
-public 只输出public方法和域
-protected 只输出public和protected类和成员
-package 只输出包,public和protected类和成员,这是默认情况
-p -private 输出所有类和成员
-s 输出内部类型签名
-c 输出分解后的代码。 eg:类中每一个方法内,包含 java 字节码的指令
-verbose 输出栈大小,方法参数的个数
-costants 输出静态 final 常量

变量,常量与只读

变量:
var 变量名 : 变量类型 = 变量初始值
getter/setter方法

不可变的变量:
var 与 val 声明的变量,最本质的区别是:val 不能有 setter (无setter,就无法改变了)

package zyf.kt

class Hello{
    //定义一个可空String类型的变量str
    //赋值 null
    var str: String? = null
//        直接在下面敲get/set,就可以重写 str 的get/set方法
    get() {
        return "$field-----invoke get-----"
    }
    set(value) {
        field = "$value-----invoke set-----"
    }

    //定义一个可空的String类型的不可变变量
    //赋值null
    //此时发现,重写set方法的时候编译器报错了
    //提示:a 'val' property cannot have a setter
    val str2: String? = null
    get() = "$field-----invoke get-----"
//    set(value) = "$value-----invoke set-----"
}

关于不可变的变量

package zyf.kt

import java.util.*

class Person(var birthYear: Int){

    /**
     * 1,此处定义的是不可变的变量 age
     */
    val age: Int
        get() {
            //3,原因:birthYear 的更改导致 age 发生了改变
            //所以 使用 val 定义的变量,不一定是常量
            //只是不能进行二次赋值的操作
            return Calendar.getInstance().get(Calendar.YEAR) - birthYear
        }

    fun afterOneYear(){
        //模拟一下一年之后
        birthYear--
    }

}

fun main(args: Array<String>) {
    val person = Person(1994)
    println("当前的年龄是:${person.age}")
    person.afterOneYear()
    //2,可以发现输出的age是不同的,说明age发生改变了
    println("一年后的年龄是:${person.age}")
}

关于常量

package zyf.kt

/**
 * const 关键字 只能修饰 object 的属性,或者 top-level 变量
 * const 变量的值,必须在编译期间确定下来,所以它的类型
 *      只能是 String 或 基本类型
 *
 */
//这就属于顶级变量,不被包含在任意类或函数中
const val age=10
const val name:String="zyf"

object A{
    const val a = 20
}

class B{
    //不可用于修饰 class 中的属性
    const val b = 10;
}

fun main(args: Array<String>) {

    //不可改变
    age=1
    name="h"
}

不可变的变量不是常量

关于 object 与 class

object 声明的类,内部不允许有构造方法,类似于java的单例类。

fun main(args: Array<String>) {

    //不可改变
//    age=1
//    name="h"
    val a1=A
    val a2=A
//    为true,说明是一个对象
    println(a1===a2)
}

使用 javap 命令反编译查看 object A 生成的 .class 信息
* 定义的 const 就是 java 中的常量
* 创建的 a1 、 a2 变量,实际上都是这个 instance

展开阅读全文

没有更多推荐了,返回首页