Kotlin
Kotlin是为了解决java不好用,Scala 太难用的问题所产生的编译型语言 ,可以运行在java虚拟机上,语法简洁,具备现代高级语言特性 能和java遗留代码无缝互操作。 kotlin脱胎于旧预言,解决了java开发的很多痛点。跨平台特性 可以用Kotlin开发各种类型的原生应用 它可以脱离虚拟机层 直接编译成可以在Windows,Linux和macOS平台上运行的原生二进制代码 Kotlin工作原理 :开发了一门新的编程语言,然后自己做了编译器,让它将这门新语言的代码编译成同样规格的class文件,只要是符合规格的class文件,java虚拟机都能识别
Kotlin的优缺点
Kotlin的优点
- Kotlin更安全:
Kotlin 支持显式地声明 null ,并确保开发人员不会遇到可能导致质量问题的空引用异常; - 代码简洁:
不需要分号 、很多相同的功能去用Kotlin实现语法更简洁 - 函数式支持:
高阶函数 - 扩展函数:可以直接不需要修改某个类的源码而给这个类添加新的功能
- 内联函数:使用 Lambda 表达式时,这些内联函数让它比 Java 编写的代码运行得更快;
- 支持线程的并发协同:Kotlin中当取消一个线程执行的时候,并不会阻塞任何其他线程,Java 虽然也允许多线程在后台运行,但它的处理机制更加复杂,在处理长时间运行的网络 I/O 或 CPU 密集型任务方面,Kotlin 比 Java 更具有领先优势;
Kotlin的缺点
目前,它还不支持很多功能,比如静态成员、通配符类型、非私有字段、Checked Exception、原始类型以及三元运算符等等。
变量常量与类型
参数定义
而参数定义,在Kotlin中遵循的左侧参数名 ,右侧数据类型的定义方式: 参数名:数据类型
var a:Int
var b:String
val c:Boolean
val d:Double
而由于Kotlin支持上下文联想,所以有时候我们可以省略右侧的数据类型。Kotlin会自动根据左侧的计算结果给右侧的对象赋值相应的类型。
var maximumAge:Int = 5
变量定义关键字 变量名 类型定义 赋值运算符 赋值
只读变量
要声明可修改变量,使用var关键字 要声明只读变量,使用val关键字 对应于Java中的final修饰符 Kotlin完全抛弃基本数据类型 ,全部使用对象数据类型 。 对象数据类型 Java中int是关键字,Kotlin中Int是一个类,拥有自己的方法和继承结构
类型推断
对于已声明并赋值的变量,它允许你省略类型定义
val a = 5
println(a)
编译时常量
只读变量并非绝对只读
编译时常量只能在函数之外定义,因为编译时常量必须在编译时赋值 ,而函数都是在运行时才调用 ,函数内的变量也是在运行时赋值,编译时常量要在这些变量赋值前就已经存在(包括main函数)
const val MAX = 200
fun main() {
val a = 5
println(a)
}
编译时常量只能是常见的基本数据类型 :String,Int,Double,Float,Long,Short,Byte,Char,Boolean
查看Kotlin的字节码
在idea中 shift两次+show Kotlin Bytecode
Kotlin的引用类型与基本数据类型
Java有两种数据类型,引用类型(堆内存)与基本数据类型(栈内存)
Kotlin只提供引用类型 这一种数据类型,出于更高性能的需要,Kotlin编译器会在Java字节码中改用基本数据类型
表达式
if/else if表达式
if可以有返回值,返回值为if语句中每个条件最后一行代码的返回值。
fun largerNumber(num1 : Int,num2 : Int) : Int{
val value = if(num1 > num2){
num1
}else {
num2
}
return value
}
还可以简化成:
fun largerNumber(num1:Int,num2:Int):Int{
return if(num1>num2){
num1
}else{
num2
}
}
fun largerNumber(num1 : Int,num2 : Int) = if(num1>num2) num1 else num2
range 表达式
Range表达式使用一个“..” 操作符,它是被定义实现了了一个RangeTo方法 in A…B in关键字用来检查某个值是否在指定范围之内 [A, B]
fun main() {
val age = 3;
if(age in 0..3) {
println("111")
}else if(age in 3..12) {
println("222")
}else {
println("333")
}
if(age !in 1..2) {
println("444")
}
}
Range用于任何可以被比较的类型,但对于数字类型比较器会转换为类似java的简单代码来避免额外开销来优化它。
而且注意,数字类型的Range可以用于迭代,如:
for(i in 0..10){
....
}
Kotlin区间
val range = 0..10 表示0到10的区间,两端闭。
val range = 0 until 10 表示0到10左闭右开区间。
.. 关键字创建两端闭区间。until 关键字创建左闭右开区间。step a 关键字在for-in 循环中,相当于i = i+a 的效果,每次递增a
downTo 关键字用来创建一个降序区间。
when表达式
允许你编写条件式,在某个条件满足时,执行对应的代码
只要代码包含else if分支,都建以改用when表达式
同样作为表达式也可以返回一个值 ,如:
val a = when(x){
...
}
当需要返回一个值时,由于必须要返回,所以必须覆盖所有的可能性分支或实现else,否则不会被编译成功。当不需要返回时,则不需覆盖所有可能性。
更强大的是,我们可以检测参数类型 进行判断,如:
when(view){
is TextView -> view.setText("test")
is EditText -> toast("value is ${view.getText()}")
else -> view.visibility = View.GONE
}
通过is判断后,参数会被自动转型 ,所以不需要明确的做类型转换。
它还可以检测参数是否在一个数组范围甚至是一个集合范围内 ,如:
val cost = when(x){
in 0..10 -> "cheap"
in 10..100 -> "regular"
in specialValues -> "special"
else -> "not raded"
}
它甚至可以摆脱参数 ,代替if/else链,如:
val res = when{
x in 0..10 -> "cheap"
y.contains("hello") -> "hello world"
v is EditText -> v.getText()
else -> ""
}
注意: (1)使用when时参数可以为null,如果没有匹配的分支则什么都不发生或执行else分支。
? (2)如果有多个分支满足条件,当匹配到第一个时即返回,其他匹配的分支不再执行
when 与switch 的区别:
- switch只能传入整型或短于整型的变量,JDK1.7后增加了对字符串变量的支持,switch中每个case条件都要主动加上break,否则会依次执行下面的case。
- when语句允许传入一个任意类型的参数,格式为:
匹配值->{执行逻辑} ,执行逻辑只有一行时{} 可以省略。 - when语句支持
类型匹配 ,is 关键字是类型匹配的核心,相当于Java中的instanceof 关键字,N umber是Kotlin中内置的一个抽象类,Int、Long、Float、Double等与数字相关的类都是checkNumber() 抽象类的子类。
val school = "小学"
val level: Any = when(school) {
"学前班" -> "幼儿"
"小学" -> "少儿"
"中学" -> "青少年"
else -> {
println("未知")
}
}
println(level)
变量level是任意类型的
string模板
模板支持在字符串的引号内放入变量值
还支持字符串里计算表达式的值并插入结果,添加在${} 中的任何表达式,都会作为字符串的一部分求值
val origin = "111"
val dest = "222"
println("$origin and $dest")
val flag = false
println("Answer is: ${if(flag) "我可以" else "对不起"}")
|