二、基础语法

92 阅读4分钟

基本类型

Kotlin的基本数值类型与JAVA一致:

KotlinJavaKotlinJava
BytebyteFloatfloat
ShortshortDoubledouble
IntintCharchar
LonglongBooleanboolean

Kotlin没有基本类型包装类,其基本类型即可当作JAVA包装类使用。
和 Java 不一样,Kotlin 中的 Char 不能直接和数字操作,Char 必需是单引号 ' 包含起来的。

fun check(c: Char) {
    if (c == 1) { // 错误:类型不兼容
        // ……
    }
}
其他常用数据类型KotlinJava
数组Array<T>T[]
超类AnyObject

位操作符

KotlinJavaKotlinJava
左移位shl<<and&
右移位shr>>or|
无符号左移位ushl<<<异或xor
无符号右移位ushr>>>取反inv

可见性

Kotlin有四个可见性修饰符:public、private、protected、internal,默认为public可以不写。

类内声明顶级声明
public各处可见各处可见
private类内可见文件内可见
protected同一包内,或所有子类可见--不合法--
internal同module可见同module可见

伴生

伴生代码块使用companion objectclass内声明,在class被加载时自动加载(解析),为此class所有。

class Test {
    companion object {
        val a: String = "abc"
        fun test() {
            System.out.println("test")
        }
    }
}
//Kotlin调用
Test.print(Test.a)
//JAVA调用
Test.Companion.print(Test.Companion.getA());

注意:internal在编译打包生成jar包时会被修改为public,既编译后的可见性与Javapublic关键字可见性相同。
此时可以采用Java非法命名强转的方式禁止访问:

  1. 使用@JvmName分配一个JAVA无法使用的函数名,如:{function test};
  2. 用单引号强转,Kotlin允许使用''把一个不合法的标识符强行合法化,如:'{function test}';

非空安全

Kotlin文件中声明的属性或取返回值默认都是不允许为null的,如果需要允许属性或返回值为null,则要在类型声明后面添加?

var str:String? = null
fun test(type: Int?): String? {
   return str
}

在直接调用属性值的时候,Kotlin中提供了两种null校验方式:

  1. ?.:允许调用对象为null,如果调用对象为null则直接返回null不再进行后面的调用。
  2. !!.:不允许调用对象为null,如果调用对象为null则抛出异常。

另外,由于null不属于任何类型,也可以使用类型检测区分是否为null

条件控制

if控制:在Kotlin中,if是⼀个表达式,它会返回⼀个值。因此Kotlin中取消了3级表达式。

var n1 = 1
var n2 = 3
val max = if (n1 > n2) n1 else n2

?:空判断:如果操作符前的表达式返回为null则返回操作符后的表达式结果。

var a = null
var b = "123"
val c = a ?: b // c的值为“123

when控制:类似与JAVA中的switch,将它的参数和所有的分支条件顺序比较,直到某个分支满足条件。如果它被当做表达式,则第⼀个符合条件的分⽀的值就是整个表达式的值。

fun test(type: Int) {
    val result: String? = when (type) {
        1 -> "type 1"
        2 -> {
            "type 2"
        }
        else -> null
    }
    System.out.println(result)
}

循环控制

for循环:for循环可以对任何提供迭代器(iterator)的对象进行遍历。写法有以下3种:

fun test(strArr: Array<String>) {
    for (s in strArr) {}//直接遍历对象
    for (i in 0..2) {}//遍历区间[0,2]下标,即0至2
    for (i in 0 until 3) {}//遍历区间[0,2)下标,即0至2
    for (i in strArr.indices) {}//按照有效下标遍历
}

whiledo...while循环:

while(布尔表达式) {
    //循环代码语句
}
do {
    //循环代码语句
} while(布尔表达式);

对于while语句而言,如果不满足条件,则不能进入循环,不同的是,do…while循环至少会执行一次。

在循环中Kotlin⽀持传统的breakcontinuereturn操作符,具体用法与Java一致。

捕获异常

Kotlin中与Java一样使用throw抛出异常,使用trycatchfinally捕获处理异常,2者主要区别在于:

  1. Kotlin中没有受检异常;不再需要在方法后声明可能产生的异常类型,调用时也就不必添加trycatch代码块对可能的异常进行处理;如果仍然希望在代码中声明可能产生的异常类型,需要使用@Throws注解。
  2. Kotlin中的trycatchfinally可作为表达式使用;
val b: String = try {
    //do some thing
    "try"
} catch (e: Exception) {
    //do some thing
    "catch"
} finally {
    "finally"//不会返回
}

trycatchfinally作为表达式使用时不能使用return,且不会得到finally内的返回值。

Nothing类型: 可以认为Nothing类型是所有类型的子类型,表明该对象不属于任何一个类型;

我们一般会在2种情况或使用到这个类型:

  1. throw表达式的返回:执行throw表达式之后不会执行方法的返回函数,此时可声明返回类型为Nothing,标记该方法的返回函数永远不能达到;
  2. 需要推测对象类型时没有明确推断信息:如果⽤null来初始化⼀个要推断类型的值,⽽⼜没有其他信息可⽤于 确定更具体的类型时,编译器会推断出Nothing?类型。
val x = null // “x”具有类型Nothing?