Kotlin和Java的一些不同点

发布于:2024-07-05 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.Kotlin 的变量是没有默认值的(因此要求初始化),Java的成员变量是有默认值的

Java的成员变量:

String name; //  默认值是 null
int count; //  默认值是 0

不过其实 Java 也只是成员变量有默认值,局部变量也是没有默认值的,如果不给它初始值也会报错

void run() {
    int count;
    count++;     // IDE 报错,Variable 'count' might not have been initialized
}

2.Kotlin中成员变量可以是抽象的

例如下面的编译器提醒,name必须被初始化,或者把他定义为抽象的,让A的子类去实现该变量
在这里插入图片描述

将name定义为抽象变量,那么A类就要相应定义为抽象类了

abstract class A {
    abstract val name: String
}

class B : A(){
    override val name: String
        get() = "daisy"
}

3.Kotlin中有局部函数(local function),而Java中没有

fun toDo() {
    //定义在函数中的局部函数
    fun hellWord() {
        println("你好")
    }
    
    hellWord()
}

4.函数参数的默认可修改性

Kotlin 函数参数默认是 val 类型,所以不需要写 val 关键字,Kotlin 里这样设计的原因是保证了参数不会被修改;而 Java 的参数默认可修改(默认没 final 修饰),会增加出错的概率。

fun increment(number: Int) {
    number = number + 1  // 这会导致编译错误,因为`number`是`val`,不能被重新赋值
}

5.静态初始化块

Java的静态初始化块:

public class MyClass {
    static int staticNumber;
    static String staticString;

    // 静态初始化块
    static {
        staticNumber = 42;
        staticString = "Hello, World!";
    }
}

Java 中的静态变量和方法,在 Kotlin 中都放在了 companion object 中。因此 Java 中的静态初始化在 Kotlin 中自然也是放在 companion object 中的,由 init 和一对大括号表示:

class Sample {
    companion object {
        init {
            ...
        }
    }
}

6.可见性修饰符

  • private。Java 中表示类中可见,作为内部类时对外部类「可见」;Kotlin 中的表示类中或所在文件内可见,作为内部类时对外部类「不可见」
  • Java不加修饰符时(默认),表示在同一个package中可见,在Kotlin中被弃用掉了
  • protected。Java 的 protected 子类可见 + 同一包中可见;Kotlin 的 仅有子类可见
  • public。Java和Kotlin的效果相同,都是可见性最大,哪里都可以引用。但是Kotlin不写可见性修饰符时就是public的效果(默认)
  • internal。这是Kotlin独有的,表示修饰的类、函数仅对 module 内可见
private Java中无修饰符 protected public internal
Java 仅本类中可见
(作为内部类时对外部类可见)
同一包内可见 同一包中可见
且子类可见
所有位置可见 -
Kotlin 仅本类中可见
(作为内部类时对外部类不可见)
- 仅子类可见 所有位置可见 同一模块内可见

7.多分支结构

  • Java和Kotlin的区别

在 Java 中,当多种情况执行同一份代码时,可以这么写:

switch (x) {
    case 1:
    case 2: {
        System.out.println("x == 1 or x == 2");
        break;
    }
    default: {
        System.out.println("default");
    }
}

而 Kotlin 中多种情况执行同一份代码时,可以将多个分支条件放在一起,用 , 符号隔开,表示这些情况都会执行后面的代码:

when (x) {
    1, 2 -> print("x == 1 or x == 2")
    else -> print("else")
}
  • Kotlin独有

使用 in 检测是否在一个区间或者集合中:

when (x) {
    in 1..10 -> print("x 在区间 1..10 中")
    in listOf(1,2) -> print("x 在集合中")
    // not in
    !in 10..20 -> print("x 不在区间 10..20 中")
    else -> print("不在任何区间上")
}

或者使用 is 进行特定类型的检测:

val isString = when(x) {
     is String -> true
     else -> false
 }

还可以省略 when 后面的参数,每一个分支条件都可以是一个布尔表达式:

when {
    str1.contains("a") -> print("字符串 str1 包含 a")
    str2.length == 3 -> print("字符串 str2 的长度为 3")
}

8.相等性检查

在Java中,相等性检查分为两种类型:

  • 引用相等性:使用 == 操作符。当两个引用指向内存中的同一个对象时,结果为 true。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false,因为s1和s2指向不同的对象
  • 内容相等性:使用 .equals() 方法。这个方法通常在 Object 类中定义,并可被重写以检查两个对象的内容是否相等。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1.equals(s2)); // true,因为s1和s2的内容相同

Kotlin为相等性检查提供了更加清晰的语法:

  • 引用相等性:使用 === 操作符。当且仅当两个引用指向相同的对象时,结果为 true。
val s1 = String("hello")
val s2 = String("hello")
println(s1 === s2) // false,因为s1和s2指向不同的对象
  • 内容相等性:使用 == 操作符。在底层,== 实际上是调用 .equals() 方法
val s1 = String("hello")
val s2 = String("hello")
println(s1 == s2) // true,因为s1和s2的内容相同

如果需要检查对象是否为 null 或比较可能为 null 的对象,Kotlin 的 == 还会处理 null 安全性,这在 Java 中需要显式处理。

引用相等性 内容相等性
Java == equals()
Kotlin === ==


参考文章:
Kotlin 里那些不是那么写的


网站公告

今日签到

点亮在社区的每一天
去签到