Java为解释型语言,JVM为解释器,将编译后的class文件解释成计算机可以识别的二进制数据后执行。
变量
类型推导机制
可变变量定义:var 关键字
var <标识符> : <类型> = <初始化值>(无需“;”)
var name:String = "JOJO"
var info:Int = 88
var info1:Char = 'A'
不可变变量定义: val 关键字,只能赋值一次的变量(有点类似Java中的final修饰的变量)
val <标识符> :<类型> = <初始化值>
val name:String = "JOJO"
kotlin是静态语言,在编译期就决定了var类型
kotlin完全抛弃了Java的基本数据类型,全部使用了对象数据类型。
kotlin提供了val和var关键字,必须由开发者主动声明该变量是可变的还是不可变的。
使用技巧:优先使用val来声明一个变量,当val无法满足你的需求时再使用var.
查看编译的class文件
1.
2.
点击需要查看的kt文件
3.点击Decompile,查看编译的java class文件
函数
fun时定义函数的关键字
fun 函数名(参数名: 参数类型,参数名:参数类型):返回数据类型{
函数体
}
//void == :Unit
fun main() :Unit{
println(add(1,1))
add2(1,2,3)
}
fun add(number1:Int,number2:Int) : Int{
return number1 + number2
}
//返回类型 类型推导 Int
fun add1(number1: Int,number2: Int) = number1 + number2
//可变参数 vararg
fun add2(vararg values:Int){
}
//lambda表达式函数 是val,不是fun
val add3 : (Int,Int) -> Int = {
number1 , number2 -> number1 + number2
}
程序逻辑控制
if同java,但他是有返回值的,返回值就是if语句每一个条件中最后一行代码的返回值
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2
when条件语句
匹配值 -> { 执行逻辑 }
fun main(){
val num = 123
checkNumber(num)
}
fun checkNumber(num: Number){
when(num){
is Int -> println("Is Int")
is Double -> println("Is Double")
else -> println("number dont support")
}
}
for - in 循环
区间
val range = 0 .. 10 双端闭区间 [0,10]
val range = 0 until 10 单端闭区间 [0.10)
for (i in 0 until 10 step 2)
downTo 降序区间
循环与标签 rrr@ break @rrr this@jojo.name
fun main(){
rrr@ for (i in 1..10){
for (j in 1..10){
println("i:$i,j: $j")
if(i == 5) break@rrr
}
}
}
字符串模板
kotlin NULL的保护机制
类与对象
class默认为public final,可省略
var person = Person() 实例化,去掉new关键字
次构造必须调用主构造
在kotlin中全部都是没有默认值的
open class Person(val name: String, val age: Int) {
init {
println("$name is eating. He is $age years old")
}
}
fun main(){
val person = Person("a123",18)
}
class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name,age) {
//Student的主构造函数name和age两个字段,不能将它们声明为val
//因为在主构造函数中声明成val或var的参数将自动成为该类的字段,会导致和父类同名的name和age造成冲突
constructor(name: String,age: Int): this("",0,name,age)
constructor():this("",0)
}
在Student类的主构造函数中增加name和age这两个字段时,不能再将它们声明成
val,因为在主构造函数中声明成val或者var的参数将自动成为该类的字段,这就会导致和父
类中同名的name和age字段造成冲突。
kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)
class Student(val sno: String, val grade: Int, name: String, age: Int) :
Person(name, age) {
constructor(name: String, age: Int) : this("", 0, name, age) {
}
constructor() : this("", 0) {
}
}
class Student : Person{
constructor(name: String,age: Int): super(name,age){
//由于没有主构造函数,次构造函数只能调用父类的构造函数
}
}
在java中成员变量哟默认值,但是方法内部没有默认值
lateinit var懒加载
抽象类、接口
interface Study {
fun read()
fun dohomework()
}
class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name,age),Study {
constructor(name: String,age: Int): this("",0,name,age)
constructor():this("",0)
override fun read() {
println("$name is reading")
}
override fun dohomework() {
println("$name is dohomework")
}
}
fun main(){
val student = Student("jack",19)
doStudy(student) //多态
}
fun doStudy(study: Study){
study.read()
study.dohomework()
}
函数可见性修饰符
kotlin中有4种:public、private、protected、internal
数据类和单例类
数据类
data数据类
data class(id: Int,name: String)自动生成JavaBean的代码
data class CellPhone(val brand: String,val price: Double)
单例类
object Singleton{
fun method(){
println("singleton method called")
}
}
Lambda编程
kotlin集合
listOf()函数创建的是一个不可变的集合。
mutableListOf()函数创建的是可变的集合。
setOf()
mutableSetOf()
val map = HashMap<String,Int>()
map["Apple"] = 1
map["Banana"] = 2
map["Orange"] = 3
val map = mapOf("a" to 1,"b" to 2)
集合的函数API
空指针检查
可空类型系统
Kotlin将空指针异常的检查提前到了编译时期,如果我们程序存在空指针异常的风险,在编译时会直接报错。
1.if进行判空处理
2.?.操作符
3.?:操作符
这个操作符左右两边都接收一个表达式,如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。
val c = a?:b
let函数
let函数会将对象本身作为参数传递到Lambda表达式中,此时对象肯定不会空
当Lambda表达式的参数列表中只有一个参数时,可以不声明参数名,直接使用it关键字来代替
obj.let {obj2 ->
//编写具体的业务逻辑
}
fun doStudy(study: Study?){
study?.let{it.read()}
}
字符串内嵌表达式
"hello,${obj.name}"
"hello,$name" //当表达式中仅有一个变量时,,可以将两边的大括号省略
函数的参数默认值 PDF 107