用 lambda 表达式去表示 java 中的匿名类实例
在使用 java 去给一个按钮设置监听我们通常会通过创建匿名类实例, 如下
- Button.setOnClickListener(new OnClickListener()){
- @Override
- public void onClick(View v){
- Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show()
- }
- }
在 kotlin 我们可以通过传递一个 lambda 表达式去代替这个实例
- btn_test.setOnClickListener { view : View ->
- Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show()
- }
可以以这种方式去实现的原因是 OnClickListener 接口只有一个抽象方法, 这种接口在 kotlin 中被当作函数式接口, 或者 SAM 接口, SAM 代表单抽象方法, 类似的还有像 Runnable 和 Callable 这样的函数式接口.
把 lambda 当作参数传递给 Java 方法
我们在 java 中定义一个
- void postponeComputation(int delay,Runnable computation){
- }
然后使用 lambda 表达式去传递 Runnable 这个参数
- postponeComputation(1000){
- print("hello world")
- }
注意这个 lambda 实参编译器会自动把它转换成一个 Runnable 实例. 这种调用方式效果和显示的实现一个 Runnable 匿名对象一样
- postponeComputation(1000,object : Runnable{
- override fun run(){
- println(42)
- }
- })
但实际不一样的是, 每次调用这种语句会重复创建 Runnable 对象, 而使用 lambda 表达式作为实参如果没有访问任何来自定义它的函数变量那么只会创建一个对象.
如果想要完全等价需要这样去定义
- val runnable = Runaable{ println(42) }
- fun handleComputation(){
- postponeComputation(1000,runnable)
- }
另外如果从包围它的作用域中捕捉了变量, 每次调用就不会重用同一个实例了, 如下调用每次都会使用一个新的 Runnable 实例.
- fun handleComputation(id : String){
- postponeComputation(1000){println(id)}
- }
实际上从 kotlin1.0 起, 每个 lambda 都会被编译成一个匿名类, 如果 lambda 捕捉了变量, 每个被捕捉的变量会在匿名类中有对应的字段.
SAM 构造方法: 显式地把 lambda 转换成函数式接口.
在有的方法中需要返回一个函数式接口, 不能返回一个 lambda, 可以用 SAM 构造方法把它包装起来. 如下
- fun createAllDoneRunable() : Runnable{
- return Runnable{ println("All done") }
- }
SAM 函数名称和底层函数式接口的名称一样. SAM 构造方法只接收一个参数 - 一个被用作函数式接口单抽象方法体的 lambda, 并返回一个接口类的实例.
另外除了返回值通过 lambda 创建函数式接口外, 也可以把 lambda 生成的函数式接口放在一个变量中, 如下
- val listener = OnClickListener{
- view -> val text = when(view.id){
- R.id.button1 -> "First button"
- R.id.button2 -> "Second button"
- else -> "Unknown button"
- }
- toast(text)
- }
- button1.setOnClickListener(listener)
- button2.setOnClickListener(listener)
自己是从事了七年开发的 Android 工程师, 不少人私下问我, 2019 年 Android 进阶该怎么学, 方法有没有?
没错, 年初我花了一个多月的时间整理出来的学习资料, 希望能帮助那些想进阶提升 Android 开发, 却又不知道怎么进阶学习的朋友.[包括高级 UI, 性能优化, 架构师课程, NDK,Kotlin, 混合式开发 (ReactNative+Weex),Flutter 等架构技术资料] , 希望能帮助到您面试前的复习且找到一个好的工作, 也节省大家在网上搜索资料的时间来学习.
来源: http://www.jianshu.com/p/59a288ca654f