open : 标识这个类是可以被继承的
public private protected internal
数据类 data class CellPhone(val brand:String,val price:String)
单例类 object Singleton{}
val list=listOf()
val map=mapOf( "apple" to 1,)
a?.doSomeThing() 等价于 if(a!=null){a.doSomeThing()}
val c=a?:b 等价于 a 不为空返回a 否则 返回 b
context!!.toUpperCase() 坚信这个对象不为空
objext?.let{ it.doSomeThing()} let 函数处理全局变量判空的问题
companion object{ } 类似于java 中的静态方法
val result =with(obj){
//obj 的上下文方法
“value” //with 的返回值
}
val result=obj.run{
//obj 的上下文方法
“value” //run 的返回值
}
val result=obj.apply{
//obj 的上下文方法
}
// result=obj 返回的是调用对象的本身
conpanion object {} 关键字会产生一个伴生类 修饰的方法会在伴生类中实例的方法 。会保证只有一个伴生类对象
真正的实现静态方法:
1.使用@JvmStatic 注解 该注解只能存在于单例类或者companion object 中
2.使用顶层方法, 指没有定义在任何类中的方法
延时初始化:
private lateinit var adapter :MessageAdapter
判断延时初始化是否初始化
if(!::adapter.isInitialized)
密封类 sealed class Result
密封类放在when()中会检测出每一个子类 进行全部处理
高阶函数:如果一个函数接受另外一个函数作为参数,或者返回值的类型是另外一个函数 那这个函数就是高阶函数
(String ,Int)-> Unit
fun example(func:(string,Int)->Int){
func("123",2)
}
fun StringBuilder.build(block:StringBuilder.()->Unit):StringBuilder{
block()
}
ClassName. 表示这个函数类型是定义在哪个类当中
内联函数:inline 编译器会把内敛函数中代码在编译的时候自动替换到调用到它的地方这样就不存在内存开销了。
noiinline 非内联函数 类型参数可以自由的允许传递给其他的任何函数,他就是一个真实的参数
内联非内联函数 重要的区别:内敛函数所引用的表达式中可以使用return 关键字进行函数返回,非内联函数只能进行局部返回。return@printString
crossinline 保证内联函数中一定不会出现return 关键字返回 但是还是可以使用return@printString 进行局部返回的
泛型:泛型的定义 泛型类 泛型方法
by 委托
infix 函数关键字构建 可读性更高的语法
infix fun String.beginsWith(prefix:String )=startsWith(prefix)
if("234234" beginWith "12"){}
语法糖的特殊性:1.不能定义顶层方法 只能在类中的属性方法中进行使用
2.infex 函数只能接受一个函数,函数的类型没有限制
infix fun <T> connection<T>.has(element:T)=contains(element)
java 泛型功能通过泛型擦除功能实现的,泛型对于类型的约束只在编译时期存在,运行的时候就仍然会按照jdk1.5之前的机制来运行的.。 jvm 也是识别不出来我们在代码中的泛型类型
泛型实化
inline fun <reified T> getGenericType(){}
inline fun <reified T> getGenericType() =T::class.java
泛型实化必须要放在内联函数当中 上边方法就可以返回被实化的具体类型
val result = getGenericType<String>()
inline fun<reified T> startActivity(context:Context){
val intent=Intent(context,T::class.java)
context.startActivity(intent)
}
startActivity<TestDemo.class>(context)
inline fun<reified T> startActivity(context:Context,block:Intent.()->unit){
val intent =Intent(context,T::class.java)
intent.block()
context.startActivity(intent)
}
startActivity<TestDemo.class>(context){putExtra("param1","date")}
泛型的协变
假设定义一个MuClass<T> 的泛型类 其中A是B的子类型,同事MyClass<A> 也是MyClass<B> 的子类型那么我们称MyClass 在T 这个泛型上协变。
class SimpleData<out T> (val data:T?){
fun get():T?{
return data}
}
在泛型T的声明生加Out 关键字 不能出现在in 位置上, 意味着SimpleData在泛型T上是协变的。
泛型的逆变
定义一个MyClass<T> 泛型类 假设 A 是B的子类型,同事MyClass<B> 又是MyClass<A>的子类型 那么MyClass<T> 在T这个泛型上发生了逆变。
泛型T 的声明要在加一个In的关键字 T 只能出现在in 的位置之上 而不能出现在out 位置上
协程高效编写并发程序
开启一个协程
1.Global.launch{ println("234") }
这样开启的协程是一个顶层协程 这种协程当应用程序结束 协程也就结束了
2.runBlocking{}
保证协程作用域内的所有代码和子协程没有完全执行完之前一直阻塞当前的县城
launch 必须要在其中的作用域中执行才可以
挂起函数 suspend 必须要在另外的挂起函数或者协程的作用域中调用 有限状态机的一种优化回调 具体由虚拟机完成的
coroutineScope 也是挂起函数 特点: 会继承外部的协程作用域并且创建一个子作用域
runBlocking 创建协程的作用域 coroutineScope 创建子协程的作用域
GlobalScope.launch launch 函数会返回一个job对象
job cancel() 方法可以取消协程
val job=GlobalScope.launch{ }
job.cancel()
val job=Job()
val scope=CoroutineScope(job)
scope.launch{}
job.cancel()
async 函数必须在协程作用域中才能调用,它会创建一个新的子协程并返回一个Deferred对象,如果我们
要获取函数代码快的执行结果,需要调用Deferred对象的await() 方法。
fun main(){
runBlocking{
val result=async{ }.await()
println(result)
} }
fun main(){
runBlocking{
val start =async{
delay(1000)
5+5
}.await()
val end=async{
delay(1000)
4+6
}.await()
println("result is ${start+end}")
}}
fun main(){
runBlocking{
val deferred1=async{
delay(1000)
5+5
}
val deferred2=async{
delay(1000)
4+6
}
println("result is ${deferred1.awit()+deferred2.await()}")
}}
当一个协程的作用域中
有多个async 作用域时会串行执行的,当返回的对象是deferred 获取结果的时候再使用await()这个时候会变成并行的关系
fun main(){
runBlocking{
val result=withContext(Dispatchers.Default){
5+5
}
println(result)
}}
线程参数: Dispatchers.Default 默认地并发的线程策略
Dispatchers.IO 较高并发的线程策略 支持高并发的线程数量 比如网络请求
Dispatchers.Main 不会开启子线程 在主线程中执行代码
suspendCoroutine 函数必须在协程的作用域中或者挂起函数中使用。主要作用是立即让当前的协程挂起然后在普通的线程中执行lamba表达式 调用他的resume() 或者 resumeWithException() 让协程恢复执行。
suspend fun request(address:string) :String{
return suspendCoroutine{ continuation->
HttpUtil.senfHttpRequest(address,object:HttpCallbackListener{
onFinish(){ continuation.resume() }
onError(){ continuation.resumeWithException()}
})}}