学习kotlin 必须掌握的命令
javap [option] *.class
-I 输出行和变量的表
-public 只输出public 方法和域
-protected 只输出public 和 protected 类和成员
-package 只输出包,public 和 protected 类和成员,这是默认的
-p -private 输出所有类和成员
-s 输出内部类型签名
-c 输出分解后的代码。例如:类中每一个方法内,包含java字节码的指令
-verbose 输出栈大小,方法参数的个数
-constants 输出静态final 常量
变量、常量与只读
var <propertyName> [:<PropertyType>] [=<property_initializer>]
[<getter>]
[<setter>]
变量名 : 变量类型 = 变量初始值
getter
setter
var 与 val 申明的变量,最本质的区别是val 不能有 setter
编译时常量
const val a = 0
const 只能修饰 object 的属性,或 top-level 变量
const 变量的值必须在编译期间确定下来,所以他的类型只能是String 或基本类型
kotlin空安全是如何实现的
尝试调用空对象的成员变量或方法会触发空指针异常
- 每次引用对象的时候,都去进行对象判空、在运行期避免对象空指针 (如:java)
- 通过静态代码检查、编译插件检查,在编译期避免空指针异常
kotlin 是将两者结合,来实现空安全
内联的特殊情况
- 在kotlin 中,内部lambda 是不允许终端外部函数执行的
- inline 的lambda 可以中断外部函数调用
- crossinline 不允许inline 的lambda 中断外部函数执行
- noinline 拒绝内联
inline
inline fun test(l:()-> Unit){
l.invoke()
return
}
fun main(args Array<String>){
test{
println("hello")
//inline 的lambda 可以中断外部函数调用。此示例只会输出 “hello”
//如果test 方法没有用inline 修饰,那么在lambda 表达式中是不允许添加return 关键字的
return
//如果test方法没有用inline 修饰,那么在lambda中的return写法如下
return@test //指的是将当前闭包返回,不在执行闭包内return后面的代码
}
printlin("world")
}
crossinline
inline fun test(crossinline l:()-> Unit){
l.invoke()
return
}
//当想让hello 被直行,xiaoming 不被执行。并且world需要被直行时,使用crossinline 修饰lambda。表示不允许lambda 中断外部函数执行
fun main(args Array<String>){
test{
println("hello")
return@test //只能retutn 当前lambda
println("xioaming")
}
printlin("world")
}
//匿名函数,只能return 自己
val test = fun(){
println("test")
return
}
test()
noinline
noinline 通常用来修饰一个返回值为该lambda 的参数。如下
如果l2 lambda 不申明为noinline
inline fun test(l1:()-> Unit,noinline l2:()->Unit):()->Unit{
l1.invoke()
l2.invoke()
println("test")
return l2
}
kotlin 的真泛型与实现方法
kotlin 泛型特性
1. 支持限定泛型参数类型
//如下代码表示T 需要直接或间接继承或实现 Callback ,Runnable 类型(是其子类),t 才能被传递进来,否则编译器报错
class Test<T> where T:Callback ,T:Runnable {
fun add(t:T){
t.run()
t.callback()
}
}
class A :Callback,Runnable{
override fun callback(){
printlin("callback")
}
override fun run(){
printlin("run")
}
}
interface Callback{
fun callback()
}
fun main(args:Array<String>){
val test=Test<A>
test.add(A)
}
2.kotlin 的泛型是真泛型
kotlin 的泛型是真泛型,不会像java 泛型,在编译后参数都被抹去,直接变成object
//已gson库代码举例
java code 如下
public <T> T fromJson(String json,Class<T> classOfT){
//...
}
kotlin code 如下
inline fun <reified T> Gson.fromJson(json:String):T{
return fromJson(json,T::class.java)
}
//注:此处inline不可被省略
通过reified 修饰,告诉编译器 T 是一个真泛型,如此我们在代码运行时,就可以拿到T在运行时实际代表的那个javaClass
reified 只能用来修饰函数,不能用来修饰类
类的真泛型
class View<T>(val clazz:Class<T>){
//lazy 是线程安全的懒加载,当变量被调用时才会执行方法块
val presenter by lazy{clazz.newInstance()}
//伴生对象会在构造函数调用之前,也就是类被加载进类加载器时,就会被创建好
companion object{
inline operator fun<reified T> invoke() = View(T::class.java)
}
}
class Presenter{
orvrride fun toString():String{
return "presenter"
}
}
fun main(args:Array<String>){
val p = View<Presenter>().presenter
上述代码等同于下面代码
val b = View.Companion.invoke<Presenter>().pre
}
可用于实现mvp模式