Kotlin 实战笔记
Kotlin 的集合分为可变集合和不可变集合,不可变集合类似 Java 中的 List、Set、Map,而可变集合如 MutableList
val set1 = setOf(1, 2, 3) val set2 = hashSetOf(1, 2, 3) val set3 = mutableSetOf(1, 2, 3) val list1 = listOf(1, 2, 3) val list2 = arrayListOf(1, 2, 3) val list3 = mutableListOf(1, 2, 3) val map1 = mapOf(1 to "one", 2 to "two", 3 to "three") val map2 = hashMapOf(1 to "one", 2 to "two", 3 to "fifty-three") val map3 = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
Kotlin 中声明的函数可以指定默认的参数值:
fun <T>joinToString( collection: Collection<T>, //下面三个参数都有默认值 separator: String = "", prefix: String = "", postfix: String = "" ) {} fun main(args:Array<String>) { val list = listOf(1, 2, 3) //有默认值的参数可以不传值 joinToString(list) joinToString(list, "") joinToString(list, "", "") joinToString(list, "", "", "") }
上面这个例子中 joinToString(list, "", "", "")
的调用可以做得更优雅:
//调用时标明参数的名称 joinToString(list, separator = "", prefix = "", postfix = "")
//正确示例 joinToString(list, "", prefix = "", postfix = "") //错误示例 joinToString(list, separator = "", "", postfix = "")
在 Kotlin 中可以直接在一个 Kotlin 文件声明函数和属性,不必像 Java 那样必须在类中才能声明属性和方法。
//文件名:KotlinTest.kt package com.itscoder.ljuns.practise.kotlin.chapter3 //类似于 Java 中 private static final test1 = 0; val test1: Int = 0 //类似于 Java 中 public static final test2 = 0; const val test2: Int = 0 //类似于 Java 中 private static int test3; var test3: Int = 0 //类似于 Java 中 public static final void test() {} fun test() {}
看看编译后生成的文件:
//类名就是文件名 public final class KotlinTestKt{ private static final int test1 = 0; public static final int test2 = 0; private static int test3; public static final int getTest1() { return test1; } public static final int getTest3() { return test3; } public static final void setTest3(int var0) { test3 = var0; } public static final void test() { } }
Kotlin 可以在不修改源代码的情况下给原有的类添加函数,即拓展函数。
新建一个 kotlin 文件 StringUtil.kt:
/** * 给 String 类拓展了一个 lastChar() 的函数,拓展函数名可以和成员函数名相同 * String:接收者类型,即要拓展的类或接口 * this:接收者对象,可省略 */ fun String.lastChar(): Char = this.get(this.length - 1) // 省略 this fun String.lastChar(): Char = get(length - 1)
上面代码给 String 这个类拓展了一个返回最后一个字符的函数,用法和其他普通函数一样:
print("Kotlin".lastChar())
编译后生成的 Java 文件:
public final class StringUtilKt{ public static final char lastChar(@NotNull String $receiver){ Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver.charAt($receiver.length() - 1); } }
所以,如果是在 Java 中调用的话就是这样:
System.out.println(StringUtilKt.lastChar("Java"));
此外,拓展函数不能被重写,举个例子:
open class View{ open fun click() = println("view click") } // 继承 View open class Button:View() { // 重写 click() override fun click() = println("button click") } // 分别有拓展函数 fun View.showOff() = println("I`m a View") fun Button.showOff() = println("I`m a Button") fun main(args:Array<String>) { val view: View = Button() view.click() // 打印结果:button click // 调用拓展函数时变量类型由静态类型决定,即 View view.showOff() // 打印结果:I`m a View View().showOff() // 打印结果:I`m a View Button().showOff() // 打印结果:I`m a Button }
和拓展属性类似,可以给已存在的类添加拓展属性。
在拓展函数的例子中添加拓展属性:
/** * 给 String 类拓展了一个 lastChar 的属性,拓展属性名可以和成员属性名相同 * 必须提供对应的 gettr()、setter() 方法 */ val String.lastChar: Char get() = get(length - 1)
Kotlin 中可变参数的定义和使用与 Java 有点不同:
// 用 vararg 来声明可变参数 fun test(vararg value: String) = println(value.size) fun main(args:Array<String>) { // 这种调用和 Java 中一样 test("one", "two", "three") // Kotlin 不允许传入一个数组,要加一个特殊符号 * test(*args) }
看看编译后的文件:
public static final void test(@NotNull String... value){ Intrinsics.checkParameterIsNotNull(value, "value"); int var1 = value.length; System.out.println(var1); } public static final void main(@NotNull String[] args){ Intrinsics.checkParameterIsNotNull(args, "args"); test("one", "two", "three"); test((String[])Arrays.copyOf(args, args.length)); }
所以如果在 Java 中去调用 Kotlin 定义的可变参数,使用方式还是和以前一样的。