美文网首页禅与计算机程序设计艺术
Kotlin基础语法学习之变量(Java To Kotlin)

Kotlin基础语法学习之变量(Java To Kotlin)

作者: dasamanren | 来源:发表于2020-01-14 18:49 被阅读0次

    简介

    Kotlin基本语法对比
    本篇文章主要是为了方便Android开发者从Java转到Kotlin初期的迷茫,提供两种语言基础语法的对比,方便理解

    1 声明(常量与变量)

    在Kotlin中,声明变量有两个关键字,它们是val与var
    var:可重新赋值的变量使用var关键字,代表着变量(可读可写)
    val:只能为其赋值一次的变量使用val关键字,代表变量(只读),跟final有略微不同

    通过代码来对比
    Kotlin:

    val a: Int = 1  // 立即赋值
    val b = 2   // 自动推断出 `Int` 类型
    var c = 0  // 自动推断出 `Int` 类型
    c = 1
    

    Java:

    final int a = 1;
    final int b = 2;
    int c;
    c = 3;
    

    简单的对比可以比较清晰的看出来:
    var:定义变量的时候不带final
    val:相当于定义变量的时候带final,但是跟final又有略微的不同,到底有什么区别呢?请看接下来的"属性与字段"

    1.1 属性与字段

    首先我们需要区分一下属性和字段
    Kotlin中声明的变量,都是属性
    Java中声明的变量,都是字段
    接下来我们看看在Kotlin中声明一个变量的完整步骤来更好的理解:

    class KotlinTest {
        val a = 1
        var b = 2//属性
    }
    

    通过Decompile转换成Java看一下具体的操作

    public final class KotlinTest {
       private final int a = 1; 
       private int b = 2; //第一部分创建字段
    
       public final int getA() {
          return this.a;
       }
    
      //第二部分创建get()
       public final int getB() {
          return this.b;
       }
    
      //第三部分创建set()
       public final void setB(int var1) {
          this.b = var1;
       }
    }
    

    小结:

    • val声明的是属性,final声明的是字段
    • Kotlin中属性的声明 = Java中字段声明 + get() + set()
    • 而被val声明的属性是没有set()
    • 尽量用val,为什么要设置这两个类型声明,因为当变量不可变的时候,建议使用final标记,但是很多同学在写的时候觉得麻烦,没省略了final,为了代码的安全性,设置了val,省略了写final的步骤,更适合让同学们使用

    1.2 幕后字段 field

    在 Kotlin 类中不能直接声明字段,声明的是属性。而属性是不能保存状态的,只有字段才能保存状态,所以Kotlin在属性声明的时候,会默认创建一个字段,叫做“幕后字段”。

    var counter = 0 // 注意:这个初始器直接为幕后字段赋值
        set(value) {
            if (value >= 0) field = value// 注意:并不是直接赋值给counter,而是赋值给幕后字段
        }
    

    更多幕后属性相关请点击查看

    1.3 延时属性 lateinit

    一般地,属性声明为非空类型必须在构造函数中初始化。比如:

    var a: Person = Person()
    

    但是我们在使用Java的时候,经常是创建一个变量,并不会立即给赋值,比如:

    private Person p;
    

    这种情况下,你可以用lateinit修饰符标记该属性:

    lateinit var a: Person
    

    在初始化前访问一个lateinit属性会抛出一个特定异常,该异常明确标识该属性被访问及它没有初始化的事实。要检测一个 lateinit var 是否已经初始化过,请在该属性的引用上使用 .isInitialized

    if (::a.isInitialized) {
        println(a.name)
    }
    

    使用lateinit修饰符的时候,需要注意以下几点:

    • 该修饰符只能用于在类体中的属性
    • 只能修饰var,不能修饰val

    更多lateinit相关请点击查看
    更多属性与字段相关请查看

    2 类型

    Kotlin:

    val a: Int = 1  // 立即赋值
    val b = 2   // 自动推断出 `Int` 类型
    val c: Int  // 如果没有初始值类型不能省略
    c = 3       // 明确赋值
    

    Java:

    public final int a = 1;
    public final int b = 2;
    public final int c = 3;
    

    通过上面的对比,可以发现Kotlin与Java之间有以下几点差别

    • 写法上有区别:
      Kotlin:<属性名>: <数据类型>
      Java:<数据类型> <属性名>
    • Kotlin可以推断出属性类型,Java需要必须手动设置

    3 空安全

    在Java中,最常见的异常就是被称之为《十亿美元的错误》。就是访问空引用的成员会导致空引用异常, NullPointerException 或简称 NPE。而Kotlin 的类型系统旨在消除来自代码空引用的危险。

    3.1 可空类型与非空类型

    在Kotlin中,一个变量想要允许为空,必须加上?
    Kotlin:

    var a: String = "abc"
    a = null // 编译错误
    var b: String?
    b = null // ok
    print(b)
    val la = a.length // 正确:变量"a"不可能为空,放心使用
    val lb = b.length // 错误:变量"b"可能为空
    val lb2 = b?.length //正确:当变量"b"为空时,返回null
    

    Java:

    public String a = "abc";
    a = null; //ok
    

    3.2 空判断

    在条件中检查null:
    Kotlin:

    val b: String? = null
    val l = if (b != null) b.length else -1
    

    Java:

    String b = null;
    final int l;
    if (b != null){
        l = b.length();
    }else{
        l = -1;
    }
    

    空安全的调用:
    Kotlin:

    val a = "Kotlin"
    val b: String? = null
    println(b?.length)
    println(a?.length) // 无需安全调用
    
    //链式调用
    val name = bob?.department?.head?.name
    

    Java:

    final String a = "Kotlin";
    final String b = null;
    if (b == null){
        System.out.print("null");
    }else {
        System.out.print(b.length());
    }
    System.out.println(a.length());
    
    //链式调用
    final String name;
    if (bob != null) {
        if (department != null) {
            if (head != null) {
                name = bob.department.head.name;
            }
        }
    }
    

    小结:

    • 在Kotlin中,所有允许为null的变量必须添加?
    • 当调用的时候,对象为null的时候,会返回null,而不是报NPE错误
    • 在链式调用中,如果任意一个属性(环节)为空,这个链式调用就会返回 null。

    更多空相关的请点击查看

    4 总结

    本文只是简单的对比了Kotlin与Java的语法上的区别,然后Kotlin并不是这么简单,需要深入学习才能掌握。希望对大家有所帮助,如果文章有不足之处,请不吝指出,谢谢。

    更多Kotlin相关的请点击查看

    相关文章

      网友评论

        本文标题:Kotlin基础语法学习之变量(Java To Kotlin)

        本文链接:https://www.haomeiwen.com/subject/ovcdactx.html