官方文档
Type | Size (bits) | Min value | Max value |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 (-231) | 2,147,483,647 (231 - 1) |
Long | 64 | -9,223,372,036,854,775,808 (-263) | 9,223,372,036,854,775,807 (263 - 1) |
Float | 32 | ||
Double | 64 |
kotlin变量的使用,kotlin的基本数据类型都是引用类型,和java的String一样都是对象
不可变变量,相当于java的final修饰,申明时候必须初始化
使用原型:val 变量名:类型 = 变量值
使用举例:
val valInt = 1
val valInt2:Int = 2
valInt不指定类型,会根据赋值自动推导。val定义的变量作为常量存在,其值不可改变。
可变变量、不为null,申明时候必须初始化
使用原型:var 变量名:类型 = 变量值
使用举例
var valLong: Long = 12222
valLong = 2
var申明的变量可以改变其值,但是未申明可以为null,赋值null会报错。
可变变量、可为null,通过问号标记
使用原型:var 变量名:类型? = 变量值
使用举例
var varNullString: String?
varNullString = null
varNullString = "sss"
空安全
当对象或者变量使用问好修饰后,编译器会强制强制要求进行空安全检查,尽可能避免运行时出现空指针异常。空检查时候,如果被检查对象为null,此行代码不会执行
//定义一个可空变量
var varNullString: String?
//第一种使用方式,建议使用这种
var len = test?.length
//类似java中
//if(test!=null){
// len=test.length
//}
//第二种使用方式
len = test!!.length //这种当test为null时会报异常
//类似java中
//if (test != null) {
// len = test.length
//} else {
// 抛出异常
//}
//第三种使用方式
len = test?.length ?: 10
//类似java中
//if(test!=null){
// len = test.length
//}else{
// len = 10;
//}
官方文档
类、接口、继承、实现接口和java非常类似
类与java区别:
1、kotlin的类中字段默认时public,对外可见,修改控制访问权限时可以设置为private、protect等。
2、kotlin的类中字段默认全部实现get、set方法,需要修改这两个方法时候可以重写
3、kotlin的类可以重写init方法,此方法在类实例化时候调用,可以做初始化操作
接口与java区别
1、kotlin的接口和java有点区别可以定义包含方法体的方法,java的接口只能定义抽象方法。
2、kotlin接口可以定义变量,和接口中的方法一样,类实现接口时必须重写字段。
可见性
可见性官方文档
关键字 | 可见范围 |
---|---|
public | 任何看到声明类的客户都会看到其public成员 |
private | 表示仅在此类中可见(包括其所有成员) |
protected | 与private子类中的+可见相同 |
internal | 模块内可见 |
继承、实现
kotlin和java一样,只能单继承,可以实现多个接口
原型
class 类名{
}
或者
class 类名:接口1,接口2,接口3,父类{
}
使用举例
定义父类ClassParent,open关键字修饰后才可以被继承
open class ClassParent(data: String) {
/**
* 父类中字段
*/
var dataParent: String? = data
}
定义一个接口InterfaceParent
interface InterfaceParent {
/**
* 抽象字段
*/
var dataInterface: String
/**
* 接口中的抽象方法,实现接口后必须重写
*/
fun setData(data: Int)
/**
* 接口中带方法体的方法
*/
fun setData2(data: Int) {
//接口中的方法可以有方法体
}
}
ClassA实现接口InterfaceParent、继承父类ClassParent
class ClassA : ClassParent, InterfaceParent {
var dataA: Int? = null
/**
* 接口中的抽象字段,实现接口时候必须重写
*/
override var dataInterface: String = ""
/**
* 类的初始化块
*/
init {
dataInterface = "类的初始化块"
}
/**
* 父类有一个带参数的构造方法,子类必须重写
*/
constructor(data: String) : super(data) {
}
/**
* 多参数构造方法
*/
constructor(data: String, dataA: Int?) : super(data) {
this.dataA = dataA
}
/**
* 重写InterfaceParent中方法
*/
override fun setData(data: Int) {
dataA = data
}
}
kotlin中方法概念和java相同,方法原型和java不同,功能比java强大,支持函数作为参数和返回值(高阶函数)
普通方法
方法原型
fun 方法名(参数1:参数类型,参数2:参数类型):返回值类型{
//实现功能
}
使用举例
无参无返回
/**
* 定义一个无参方法打印data的值
* 方法返回值是void
*/
fun printData() {
Log.i(log, "data=$data")
}
有参有返回值
/**
* 定义参数为String、Boolean的方法
* 方法返回值是Boolean
*/
fun printData(d: String, b: Boolean): Boolean {
data = d
this.b = b
Log.i(log, "data=$data ; b=${this.b}")
return b
}
参数默认值方法
方法定义时候参数设置默认值,调用方法时候有默认值的参数可以不传递,kotlin自动使用默认值
使用举例
定义方法reformat,normalizeCase、upperCaseFirstLetter默认为true,divideByCamelHumps默认false
fun reformat(
str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false
) {
//实现功能
}
使用reformat方法
reformat("")
reformat("", false)
reformat("", false, upperCaseFirstLetter = false)
reformat("", false, upperCaseFirstLetter = false, divideByCamelHumps = false)
方法原型
使用举例
高阶函数(详见底部高阶函数介绍)
官方文档
kotlin静态方法、变量类似java中public static final修饰的变量、方法,使用companion object包裹即可,常量需要const修饰
companion object {
//放置静态方法、变量
}
使用举例
定义一个类
class StaticData {
companion object {
//常量需要const修饰
const val staticVal = "类似于java的public static final "
var staticVar = ""
fun setStaticData(data: String) {
staticVar = data
}
}
}
使用静态常量、方法
val temp = StaticData.staticVal
StaticData.staticVar = temp
StaticData.setStaticData(temp)
官方文档
if使用
与java中if类似使用
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
for使用
与java的for类似使用,功能略强
collection为定义的集合,step count为循环步进,默认为1
for (item in collection step count){
print(item)
}
在1-3之间遍历,步进为1
for (i in 1..3) {
println(i)
}
在1-6之间遍历,步进为2
for (i in 6 downTo 0 step 2) {
println(i)
}
when使用
类似java的switc,功能比switch强大,case条件可以时常量、集合、表达式、类型,when条件可以时一个表达式
val list = ArrayList()
var data = 1
when (data) {
1 -> {
//等于1
}
2 -> {
//等于2
}
in 3..5 -> {
//在3-5之间
}
in list -> {
//在list集合中
}
!in 6..7 -> {
//不在6-7之间
}
is Int -> {
//类型为Int时候
}
else -> {
//其它,default
}
}
官方文档
百度百科定义协程:
协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。
需要单独依赖库
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_coroutines"
通过GlobalScope使用,Dispatchers定义协程执行在什么线程,可选IO、MAIN、Default,耗时操作一般在IO线程执行,kotlin通过线程池管理IO线程;刷新界面使用MAIN,默认在调用处所在线程时使用Default。GlobalScope.launch执行时候会有一个返回值,调用返回值中的
join方法可以让主协程或者线程卡在join处,直到子协程执行完成;
cancel方法取消协程;
cancelAndJoin方法取消并等待子协程
GlobalScope.launch(Dispatchers.IO) {
}
使用举例
1、开启子线程执行任务
GlobalScope.launch(Dispatchers.IO) {
//这里是在子线程
//延迟500毫秒
delay(500)
Log.i(log, "这里是协程1,Thread id=${Thread.currentThread().id}")
}
2、子线程执行,结果返回主线程
GlobalScope.launch(Dispatchers.Main) {
val job = GlobalScope.launch(Dispatchers.IO) {
//这里是在子线程
delay(2000)
Log.i(log, "这里是IO协程,Thread id=${Thread.currentThread().id}")
}
//这里是在UI线程
//主协程会阻塞在这里,直到子协程执行完成
job.join()
//取消任务
//job.cancel()
//取消job并且等待它完成
//job.cancelAndJoin()
Log.i(log, "这里是Main协程,Thread id=${Thread.currentThread().id}")
}
3、定时任务
GlobalScope.launch(Dispatchers.IO) {
repeat(10) { i ->
//这里是在子线程,10此重复时,每次的线程可能不相同
Log.i(log, "I'm repeat $i ...,Thread id=${Thread.currentThread().id}")
delay(100)
}
}
高阶函数简单理解就是函数的参数或者返回值是函数的函数
原型
fun hight(a:funA,b:funB):funC{
}
使用举例
普通2个普通函数,返回Int类型数据,kotlin中函数的定义可以和变量一样使用val定义
private val data1 = fun(): Int {
return 10
}
private val data2 = fun(): Int {
return 2
}
将函数用作一个函数的返回值的高阶函数
fun getData2(): () -> Int {
return data2
}
定义高阶函数higherFunction
/**
*
* @param aFun 一个无参数,返回值类型为Int的函数类型
* @param cFun 一个无参数,返回值类型为Int的函数类型
* @param bFun 一个有两个Int类型参数,返回值类型为Int的函数;类型
* @return Int类型
*/
private fun higherFunction(
aFun: () -> Int,
cFun: () -> Int,
bFun: (a: () -> Int, b: () -> Int) -> Int
): Int {
//将参数a、c传入到参数b(函数),得到结果
return bFun.invoke(aFun, cFun)
}
定义高阶函数higherFunctionAdd
/**
* 高阶函数higherFunctionAdd、higherFunctionSubtract、higherFunctionMult
* @param aFun 一个无参数,返回值类型为Int的函数
* @param bFun 一个无参数,返回值类型为Int的函数
* @return Int类型
*/
private val higherFunctionAdd = fun(aFun: () -> Int, bFun: () -> Int): Int {
//调用函数aFun、bFun
return aFun.invoke() + bFun.invoke()
}
定义高阶函数higherFunctionSubtract
private val higherFunctionSubtract = fun(aFun: () -> Int, bFun: () -> Int): Int {
//调用函数aFun、bFun
return aFun.invoke() - bFun.invoke()
}
定义高阶函数higherFunctionMult
private val higherFunctionMult = fun(aFun: () -> Int, bFun: () -> Int): Int {
//调用函数aFun、bFun
return aFun.invoke() * bFun.invoke()
}
使用高阶函数
//使用高阶函数higherFunction,实际是data1 + data2 ,(10 + 2)
val res = higherFunction(data1, getData2(), higherFunctionAdd)
//使用高阶函数higherFunction,实际是data1 - data2 ,(10 - 2)
val res2 = higherFunction(data1, getData2(), higherFunctionSubtract)
//使用高阶函数higherFunction,实际是data1 * data2 ,(10 * 2)
val res3 = higherFunction(data1, getData2(), higherFunctionMult)