Kotlin语法
变量和函数
变量
1.由val和var声明变量,其中val声明不可变变量,var声明可变变量(建议所有变量开始由val修饰,后根据需要选择用var修饰)
2.也可以显示的声明变量类型,如val a : Int = 10
3.数据类型:

函数
1.标准形式:
1 | fun methodName(param1: Int, param2: Int):Int{ |
2.语法糖:
当一个函数只有一行代码时,可以直接将那行代码直接写在函数定义的尾部用等号连接
fun largeNumber(num1: Int, num2: Int) = max(num1,num2)
程序的逻辑控制
if条件句
1.写法和Java的一样
2.和java不一样的点在于它可以有返回值,如:
1 | fun largeNumber(num1: Int, num2: Int) : Int{ |
可以用语法糖简化为:
1 | fun largeNumber(num1: Int, num2: Int) = if(num1 > num2) num1 else num2 |
when条件句
1.由这个例子说明:
1 | fun getScore(name:String)=if(name=="Tom"){ |
这段显得冗杂可以用when简化
1 | fun getScore(name:String)=when(name){ |
2.标准格式:
匹配值 -> { 执行逻辑 }(执行逻辑只有一行时括号可省)
3.类型匹配:
1 | fun checkNumber(num:Number)=when(num){ |
4.不在when中传入参数:(用得少)
1 | fun getScore(name:String)=when{ |
5.有些情况必须用4中方法:
假设所有名字以“Tom”开头的人分数只有86:
1 | fun getScore(name:String)=when{ |
循环语句
1.while循环和之前学的一样不再赘述
2.Kotlin中区间表示:
val range = 0..10两端都是闭区间
val range = 0 until 10左闭右开区间
val range = 10 downTo 1降序区间两端都是闭区间
3.step关键字相当于i++
2.for-in循环:
1 | for(i in 0..10){ |
面向对象编程
类和对象
创建方法和之前的一样,实例化有区别,去掉了new关键字:
val p=Person()
继承与构造函数
1.开放继承权限(kotlin中非抽象类默认不可继承),在类前加上open关键字即可
1 | open class person{ |
2.继承,关键字由之前的extends变为了冒号,例如:
1 | class Student : Person(){ |
Person后有一个括号是因为子类构造函数必须调用父类的构造函数
3.构造函数分为主构造函数和次构造函数:
主构造函数(没有函数体,逻辑写在init中):
1 | class Student(val sno String,val grade :Int):Person(){ |
继承来的数据不需要用val或var修饰
1 | class Student(val sno :String,val grade :Int, name:String,age:Int):Person(name,age){ |
次构造函数(几乎不会用到)
当一个类既有主构造又有次构造函数,所有次构造函数都必须直接或间接调用主构造函数:
1 | class Student(val sno :String,val grade :Int, name:String,age:Int):Person(name,age){ |
只有次构造而没有主构造时:
1 | class Student:Person{ |
此时没有显式的定义主构造函数,又有次构造可以认为其没有主构造,既然没有主构造,那么Person类后也不需要加括号了
接口
1.接口和java也基本一样,接口中函数不要求有函数体
1 | interface Study { |
2.接口关键字也使用冒号
1 | class Student(name:String,age:Int):Person(name,age),Study { |
调用如下:
1 | fun main(){ |
3.kotlin中特有的功能:允许对接口中定义的函数进行默认实现
1 | interface Study { |
修饰符
1.public:
默认项,和java的一致
2.private:
只对当前类内部可见
3.protected:
只对当前类和子类可见
4.internal:
只对同一模块中的类可见

数据类与单例类
1.数据类:
在class前加上data关键字
2.单例类:
作用:避免创建重复的对象
用法:将class换成object即可
调用:
1 | object Singleton{ |
集合的创建和遍历
listOf(不可变集合)
创建和遍历:
1 | val list= listOf("Apple","Banana","Pear") |
mutableListOf(可变集合)
创建和遍历:
1 | val list= *mutableListOf*("Apple","Banana","Pear") |
setOf和mutableSetOf
用法和listOf和mutableListOf一模一样,只是setOf和mutableSetOf中不能放重复元素
Map集合(键值对形式)
1.添加和读取数据用下标法
1 | val map=HashMap<String,Int>() |
2.简化(使用mapOf和mutableMapOf):
1 | val map= mapOf("Apple" to 1,"Banana" to 2,"Oramge" to 3) |
Lambda
1.语法结构:
{参数名1:参数类型,参数名2:参数类型 -> 函数体}(函数体可以编写任一行代码,最后一行代码会自动作为返回值)
2.一些简化点:(函数API实例说明)
1 | val maxLengthFruit = list.maxBy({fruit:String->fruit.length}) |
(1)当Lambda参数是函数最后一个参数时可以将lambda表达式移到函数括号的外面
1 | val maxLengthFruit = list.maxBy(){fruit:String->fruit.length} |
(2)当Lambda参数是函数唯一一个参数时可以将函数的括号删掉
1 | val maxLengthFruit = list.maxBy{fruit:String->fruit.length} |
(3)因为Kotlin具有类型推到机制大多情况不需声明类型
1 | val maxLengthFruit = list.maxBy{fruit->fruit.length} |
(4)当表达式参数列表只有一个参数时,也可以不声明参数名,用it来代替
1 | val maxLengthFruit = list.maxBy{it.length} |
3.map函数(对集合元素映射转化)
1 | val list= listOf("Apple","Banana","Pear") |
4.filter函数(过滤集合中的数据)
1 | val list= listOf("Apple","Banana","Pear") |
这里先调用filter再调用map效率更高
5.any和all函数
any函数用来判断集合中是否至少存在一个元素满足指定条件
all函数用来判断集合中是否所有元素都满足指定条件
1 | val list= listOf("Apple","Banana","Pear") |
Java函数式API的使用
1.使用前提:
kotlin中调用一个java方法,并且该方法接收一个java单抽象方法接口参数,就可以使用函数式API(Java单抽象方法接口指的是接口中只有一个待实现的方法)
2.实例说明:
(1)Runnable实例kotlin形式
1 | Thread(object:Runnable{ |
(2)只有一个方法可以将方法名省去
1 | Thread(Runnable{ |
(3)如果一个java方法参数列表中有且仅有一个java单抽象方法接口参数,可以将接口名省去
1 | Thread({ |
(4)根据lambda表达式可以更精简为
1 | Thread{ println("Thread is running") |
空指针检查
kotlin将空指针判定提前到了编译环节
可空类型系统
在类名的后面加一个问号表示可为空的类型
如Int表示不可为空的整型,Int?表示可为空的整型
判空辅助工具
1.”?.”操作符:
当对象不为空时正常调用,为空时啥也不干
2.“?:”操作符:
操作符左右两边均接收一个表达式,如果左边表达式不为空就返回左边否则返回右边
以上两种方法结合使用:
1 | fun getTextLength(text:String?)=text?.length?:0 |
3.空指针检查机制可能出问题:
可以使用非空断言工具,在对象后面加**“!!”**,使其强行通过编译(写法有风险,谨慎使用)
1 | val upperCase=content!!.toUpperCase() |
4.辅助工具—-let:(函数)(let可以处理全局判空问题而if无法做到)
(1)形式:
1 | obj.let{ obj2-> |
其中obj2和obj是一个对象,防止变量重名故改为obj2
(2)优化:
?.和let结合使用
1 | fun doStudy(study:Study?){ |
可以简化为
1 | fun doStudy(study:Study?){ |
Kotlin一些小技巧
字符串内嵌表达式
可以用**${}**语法结构来代替加号连接符
1 | println("hello,${obj.name}.nice to meet you!") |
如果表达式仅有一个变量时还可以将大括号省去
函数的参数默认值
不需要一一对应,可以使用键值对传参
1 | fun printParams(num:Int=100,str:String){//num:Int=100即设定了默认值 |
下划线写法
在一些方法中如果只有部分参数使用到,未使用的参数可以用下划线代替
as
kotlin中类型强制转换时使用的关键字
内部类
用inner class关键字来定义内部类




