Java 属于解释性语言。Java 代码编译之后生成的并不是计算机可识别的二进制文件,而是一种特殊的 class 文件,这种 class 文件只有 Java 虚拟机(Android 中叫 ART,一种移动优化版的虚拟机)才能识别,而这个 Java 虚拟机担当的其实就是解释器的角色,它会在程序运行时将编译后的 class 文件解释成计算机可识别的二进制数据后再执行。
Kotlin 的工作原理也是基于 Java 虚拟机之上的,因为 JVM 识别的是符合规格的 class 文件,所以 Kotlin 只需要用自己的编译器将代码编译成同样规格的 class 文件即可。
// 区别于 Java,末尾不需要加分号 funmain(){ val a = 10 println("a = " + a) // 一些情况下,比如说对一个变量延迟赋值时,类型推导机制则无法正常工作,需要显式地声明变量类型 // Int 代表一个类,它有自己的方法和继承结构,是对象数据类型。不同于 Java 的 int 为基本数据类型,int 是关键字。 val b : Int = 20 println("b = " + b) }
// 可为 null // var ss:String?=null // 不能 null,必须引用类型 // lateinit var str:String // 懒加载 // val str:String by lazy("by lazy string")
在 Java 中,一个好的编程习惯是,除非一个变量明确允许被修改,否则都应该给它加上 final 关键字。而在 Kotlin 中,可以永远优先使用 val 来声明一个变量,而当 val 没办法满足需求时再使用 var。
funlargerNumber3(num1: Int,num2: Int): Int { // 相较于 Java,这里的 if 语句是可以有返回值的。 // 因为不涉及重新赋值的情况,可以用 val 关键字。 // val value = if (num1 > num2){ // num1 // }else{ // num2 // } // return value
returnif (num1 > num2){ num1 }else{ num2 } }
funlargerNumber4(num1: Int,num2: Int): Int = if (num1 > num2){ num1 }else{ num2 }
funlargerNumber5(num1: Int,num2: Int): Int = if (num1 > num2) num1 else num2
/** * 这里的 name 和 age 没有用关键字声明。 * 因为主构造函数中声明 val 或者 var 的参数将自动成为该类的字段, * 这就会导致和父类中同名的 name 和 age 字段造成冲突。 * 因此这里不用加任何关键字,让它的作用域仅限定在主构造函数当中即可。 */ classStudent(val sno: String,val grade: Int,name:String,age:Int) : Person(name,age) {
}
1 2 3
funmain(){ val student = Student("a123",5,"Jack",19) }
// Kotlin 中提供了更加简单的函数 // 这里的 to 并不是关键字,而是一个 infix 函数。 val map2 = mapOf("Apple" to 1,"Banana" to 2) // 将 Map 的键值对变量声明到了一对括号里 for ((fruit,number) in map2){ println("fruit is " + fruit + ", number is " + number) } }
funmain(){ // 找到集合中单词最长的 val list = listOf("Apple","Orange","Banana","Pear","Grape","Watermelon") var maxLengthFruit = "" for (fruit in list) { if (fruit.length > maxLengthFruit.length){ maxLengthFruit = fruit } } println("max length fruit is " + maxLengthFruit)
// 使用集合的函数式 API 来简化代码 // maxBy() 是一个普通的函数,接收的是一个 Lambda 类型的参数, // 并且会在遍历集合时将每次遍历的值作为参数传递 Lambda 表达式。 // maxBy() 的工作原理是根据传入的条件来遍历集合,从而找到该条件下的最大值。 val maxLengthFruit2 = list.maxBy { it.length } println("max length fruit is " + maxLengthFruit)
// map 函数是最常用的一种函数式 API // 它用于将集合中的每个元素都映射成另外的值, // 映射的规则在 Lambda 表示中指定,最终生成一个新的集合。 // 比如变成大写 val newList = list.map { it.toUpperCase() } for (fruit in newList){ println(fruit) } println("------") // filter 函数用于过滤集合中数据,可单独使用,也可配合 map 函数一起使用。 // 注意函数的调用顺序,先过滤再映射,会提高效率。 // 只保留长度在 5 以内的 val newList2 = list.filter { it.length <= 5 }.map { it.toUpperCase() } for (fruit in newList2){ println(fruit) } println("------")
// any 函数用于判断集合中是否至少存在一个元素满足指定条件 // all 函数用于判断集合中是否所有元素都满足指定条件 val anyResult = list.any{it.length <= 5} val allResult = list.all{it.length <= 5} println("anyResult is " + anyResult + ",allResult is " + allResult) //...... }
Java 函数式 API 的使用 在Kotlin 中调用 Java 方法时也可以使用函数式 API,只不过是有一定限制的。