Kotlin中的sam(函数式接口)详解
用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 中setVisibility() 失效原理
这篇文章主要介绍了内存泄露导致Android 中setVisibility() 失效原理,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下2022-07-07Android编程之PopupWindow隐藏及显示方法示例(showAtLocation,showAsDropDown
这篇文章主要介绍了Android编程之PopupWindow隐藏及显示方法,结合实例形式分析了showAtLocation及showAsDropDown方法实现PopupWindow控件隐藏及显示功能相关操作技巧,需要的朋友可以参考下2017-02-02解决android报错:Intel HAXM is required to run this AVD
这篇文章主要介绍了解决android报错:Intel HAXM is required to run this AVD,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11Android自定义View实现通讯录字母索引(仿微信通讯录)
本文主要介绍了Android自定义View实现通讯录字母索引(仿微信通讯录)的实现步骤与方法,具有很好的参考价值,下面跟着小编一起来看下吧2016-12-12Android控件系列之Button以及Android监听器使用介绍
Button是各种UI中最常用的控件之一,它同样也是Android开发中最受欢迎的控件之一,用户可以通过触摸它来触发一系列事件,要知道一个没有点击事件的Button是没有任何意义的,因为使用者的固定思维是见到它就想去点2012-11-11
最新评论