kotlin高级特性二(语法特性背后的知识)

学习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

varval 申明的变量,最本质的区别是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模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值