Kotlin 的 val 和 Java 的 final 有什么区别?

目录

  • 1. 前言
  • 2. 正文
    • 2.1 变量声明
    • 2.2 属性声明
    • 2.3 函数参数
    • 2.4 委托属性
  • 3. 最后
    • 参考

1. 前言

刚开始接触 Kotlin 时,常听人说 Kotlin 中的 val 就是 Java 中的 final;随着对 Kotlin 的学习,慢慢知道这句话多么误导人。文章会从几个方面对比 Kotlin 的 val 和 Java 的 final 的区别:变量声明,属性声明,函数参数,委托属性。

2. 正文

2.1 变量声明

分别在 .java 文件和 .kt 文件中声明一个变量,看一下区别:

public class Test {
    public static void main(String[] args) {
        final int x = 5;
        // x = 6; // Cannot assign a value to final variable 'x'
    }
}
fun main(args: Array<String>) {
    val x: Int = 5
    println(x)
    // x = 6 // val cannot be reassigned
}

可以看到 final 修饰的 int 不可以被再次赋值;val 声明的 x 也不可以被再次赋值。现在看来,两者倒是有一定的共性。

2.2 属性声明

同样看一下例子:
Kotlin 的例子:

class Man {
    var age: Int = 17
    val isAdult: Boolean
        get() = age >= 18
}

fun main(args: Array<String>) {
    val man = Man()
    println(man.isAdult)
    man.age = 18
    println(man.isAdult)
}
/*
打印结果:
false
true
*/

Java 的例子

public class Man {
    int age;
    final boolean isAdult = false;

    public static void main(String[] args) {
        Man man = new Man();
        System.out.println(man.isAdult);
    }
}

对比两个例子,可以看到 isAdult 虽然在 Kolin 中声明为 val,但是它的值依然是可以变化的;而 Java 中声明为 finalisAdult 字段就不具备这个能力了。

2.3 函数参数

Kotlin 的例子:

fun release(animator: ValueAnimator) {
    animator.cancel()
    animator = null // 编译报错:val cannot be reassigned
}

Java 的例子:

public class Utils {
    public static void release(ValueAnimator animator) {
        animator.cancel();
        animator = null;
    }
    public static void release1(final ValueAnimator animator) {
        animator.cancel();
        animator = null; // // Cannot assign a value to final variable 'animator'
    }
}

可以看到在 Kotlin 中函数的参数默认就是 val 的,不可以再修改这个参数,而 Java 中必须要加上 final,才能有这个效果。

2.4 委托属性

Kotlin 中原生支持委托属性。

val lazyValue: String by lazy {
    println("computed")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)
    println(lazyValue)
}

而 Java 却却必须自己写代码实现。
Kotlin 中是有 final 关键字的,它的含义是相关成员不能被重写,类中成员默认使用。也可以显式地使用,用于重写方法禁止再被重写。
在 Kotlin 中的类和方法默认都是 final 的。

3. 最后

Java 中的 final 只能和 Kotlin 中 val 声明属性的一种情况相等。换句话说,val 包括的东西要比 Java 中的 final 多得多。需要特别说明的是,在 Kotlin 中是存在 final 这个关键字的。它的含义是相关成员不能被重写,类中成员默认使用。也可以显式地使用,用于重写方法禁止再被重写。在 Kotlin 中的类和方法默认都是 final 的。

参考

  1. Kotlin 里那些「不是那么写的」
  2. Kotlin 的 Getter 和 Setter

你可能感兴趣的:(Kotlin)