Java lambda expression understand

Brief introduction

lambda expressions as java8 of new features, function-oriented programming, make the code more concise, but also improve the efficiency of programming; we, as developers, not only to learn to use, but also to understand the principles behind the operation

lambda general use

lambda rules used roughly as follows:
Ginseng number > { generation code the Lord body } (Parameters) -> \ {body codes \}
left parenthesis is not necessary when only one parameter may be omitted; the right side of the braces are not necessary if only one line of code may be omitted
small example MainActivity acquires page permissions:

private void getPermission(){
	RxPermissions permissions = new RxPermissions(this);
	permissions.request(Manifest.permission.CAMERA,
				Manifest.permission.INTERNET,)
	            .subscribe(aBoolean -> {
	               if(!aBoolean){
	                  Toast.makeText(this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();
	               }
	        });
}

-> left-hand argument aBoolean, the right is the body of code executed;
many do less than before the code, according to the previous code to implement it, like this:

.subscribe(new Consumer<Boolean>() {
    @Override
    public void accept(Boolean aBoolean) throws Exception {
        Toast.makeText(MainActivity.this, "....", Toast.LENGTH_SHORT).show();
    }
});

That the lambda expression is how to achieve?
I look at from the reverse angle, using the apk tool apktool reverse its smali to crack the code view:
in getPermission method:

.method private getPermission()V
	.locals 4
	.line 116
	new-instance v0, Lcom/tbruyelle/rxpermissions2/RxPermissions;
	invoke-direct {v0, p0}, Lcom/tbruyelle/rxpermissions2/RxPermissions;-><init>(Landroid/support/v4/app/FragmentActivity;)V
	#部分省略...
	# 这里new了一个内部类-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc
	 new-instance v2, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;

    invoke-direct {v2, p0}, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;-><init>(Lcom/iot/chinamobile/MainActivity;)V

    .line 120
    # 订阅传入了v2,也就是上面创建的内部类
    invoke-virtual {v1, v2}, Lio/reactivex/Observable;->subscribe(Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable;

    .line 125
    return-void
.end method

The above smali Code roughly meaning, creating an inner class - $$ Lambda $ MainActivity $ ccTQ_-iN8ZWh9xOrzs2GmyGpyIc, and finally the inner class listener callback subscription rights; that we look into this inner class

.class public final synthetic Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;
.super Ljava/lang/Object;
.source "lambda"

# interfaces
//实现了Consumer接口
.implements Lio/reactivex/functions/Consumer;

# virtual methods
//重写了accept方法
.method public final accept(Ljava/lang/Object;)V
    .locals 1

    iget-object v0, p0, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;->f$0:Lcom/iot/chinamobile/MainActivity;

    check-cast p1, Ljava/lang/Boolean;
	# 又去掉了MainActivity里面的方法lambda$getPermission$0
    invoke-static {v0, p1}, Lcom/iot/chinamobile/MainActivity;->lambda$getPermission$0(Lcom/iot/chinamobile/MainActivity;Ljava/lang/Boolean;)V

    return-void
.end method

The code generally means that the current internal Comsumer class implements an interface, which is why permission subscribers can subscribe to the success of the cause, and finally went back to call MainActivity of lambda $ getPermission $ 0 method; this method what is it? Do not bother, the last step in and see:
Here Insert Picture Description
is this java code:

if(!aBoolean){
 Toast.makeText(this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();

Principle summary

lambda underlying essence is to create an inner class, while the production of a static method using a lambda expression of class, this static method is the code of the theme lambda; produced by the internal class to override the call interface method; and this internal class will be passed to the caller using a lambda; as shown
Here Insert Picture Description

above is the internal implementation of the principle of lambda, and the means of achieving its second new Comsumer themselves to the same; the preparation process to help us reduce the surface a lot of work in the code, the underlying automatically help us achieved; in fact, than the new inner classes themselves more than one step, when new themselves, in FIG no second step, as the second step of the method will move to accept the code in the class methods to the interior, reduce call logical step

In the end, how to choose, eyes of the beholder, the wise see wisdom!

Published 148 original articles · won praise 41 · views 110 000 +

Guess you like

Origin blog.csdn.net/jackzhouyu/article/details/104278425