What is sam conversion
Single Abstract Method is actually a concept proposed in java8. You can understand it as a method interface
Take a look at the thread pool we use every day
ExecutorService executorService= Executors.newScheduledThreadPool(3); executorService.execute(new Runnable() { @Override public void run() { System.out.println("hello world"); } });
It is also possible to write with the lambda in java8 below.
executorService.execute(()->System.out.println("hello world"));
So the two writing methods are equivalent. But the point to be stressed here is that there is no type of lambda in java, so he must need an interface to accept it.
sam in kotlin
val executorService: ExecutorService = Executors.newScheduledThreadPool(3) //kotlin The standard writing method of anonymous inner class in executorService.submit(object :Runnable{ override fun run() { System.out.println("hello world") } })
lambda in kotlin can be written here
executorService.submit { System.out.println("hello world") }
Note here that java's lambda has no type, but kotlin's lambda has type.
In the example above, the type of kotlin's lambda is () - > unit, which has no parameters and no return value
For lambda in kotlin, look at the above figure carefully.
In fact, a runnable is created and a lambda is wrapped in the runnable, which is not directly transformed.
//kotlin Anonymous inner classes in can also be written in this way executorService.submit(Runnable { println("hello world") })
Let's explain the above code again. When the compiler of kotlin encounters the above code again, it actually helps us generate a function
The purpose of this function is to receive a lambda expression and generate the corresponding code for us
Pit of sam conversion in kotlin
The lambda in java is fake, just a sam. kotlin's lambda is true, but he supports sam. It supports sam conversion.
Here is a kotlin interface and kotlin method
interface Invokable{ fun invoke() } fun submit(invokable: Invokable){ invokable.invoke() }
Then let's look at the call:
Look at the cause of the error
Type mismatch: inferred type is () -> Unit but Invokable was expected
It indicates that we need an invokable here, but give a lambda, which does not meet the requirements, so the compilation cannot pass.
That's understandable. I've already talked about it.
fun submit2(block:()->Unit){ block.invoke() }
If we define such a function, it is obviously OK. You can use lambda directly.
Of course, if you write this every time, the function parameters are also hard to write, so let's just create an alias
typealias Funtionx = () -> Unit fun submit2(block: Funtionx) { block.invoke() }
In addition, when using sam conversion in kotlin, you must be careful with the write method of remove, for example:
We define a simple event class:
public class EventManager { interface OnEventListener { void onEvent(int event); } private List<OnEventListener> onEventListeners=new ArrayList<OnEventListener>(); public void addOnEventListener(OnEventListener listener){ onEventListeners.add(listener); } public void removeEventListener(OnEventListener listener){ onEventListeners.remove(listener); } }
Now, kotlin code, we need to add a monitor
val eventManager = EventManager() eventManager.addOnEventListener { println("onEvent$it") }
lambda is very convenient to write, but you should be careful. You can't remove it if you write like this. If you think about it carefully, the above formula is
eventManager.addOnEventListener(object : EventManager.OnEventListener { override fun onEvent(event: Int) { { println("onEvent$event") }() } })
It's the same as
eventManager.addOnEventListener(object : EventManager.OnEventListener { override fun onEvent(event: Int) { println("onEvent$event") } })
This process of creating anonymous objects has been done by the compiler. You can't touch this object.
So naturally there is no way to remove.
In this case, we can write as follows:
val onEvent = EventManager.OnEventListener { println("onEvent$it") } eventManager.addOnEventListener(onEvent) eventManager.removeEventListener(onEvent)
perhaps
val onEvent2 = object : EventManager.OnEventListener { override fun onEvent(event: Int) { println("onEvent$event") } }
Although this kind of writing is ugly, it is concise and comprehensive, without ambiguity or error.
"The Qing Dynasty was closed to the outside world, and learning technology required exchanges and information.". Here I have prepared a lot of learning materials for you to get for free, including but not limited to java advanced learning materials, technical dry goods, large factory interview questions series, technical trends, career and other related programmer sharing
java advanced method notes, learning materials, interview questions, e-books for free, let you become the God of java Go to the top of life