前言
Lambda expression,java8的新特性。使用Lambda expression,可以替代只有一个函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。
java8还有其它一些新特性,不过在android上可能都无法使用。
studio 2.x后 支持jack编译器,使用它,能使用java8的Lambda expression,但其它特性也不敢保证就能用。
注:Android SDK中集成了JDK的一些源码,有些原生JDK中的类,可能增加了新特性的一些实现,但Android中的并没有。
还可以使用插件retrolambda来支持java8的Lambda expression。
Jack 配置
添加如下配置
android {
defaultConfig {
minSdkVersion 24 //7.0
}
jackOptions {
enabled true
}
compileOptions {//jack、retrolambda编译必需
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
以启用jack编译器,来支持Lambda expression
retrolambda 配置
项目地址:https://github.com/evant/gradle-retrolambda
retrolambda 为了兼容java5、6、7使用Lambda expression而产生。
配置如下
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'me.tatarka:gradle-retrolambda:3.6.0'
}
}
apply plugin: 'me.tatarka.retrolambda'
android {
defaultConfig {
minSdkVersion 11 //这个没有硬性要求
}
compileOptions {//jack、retrolambda编译必需
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
注:为了兼容7.0以下版本,jack方式,不适用。所以一般还是选取retrolambda
Lambda expression的使用方式
首先,我们要知道的是,该表达式,整体上是表达了一个『对象类型』。
最简单的Lambda expression
代码:
Runnable runnable = () -> System.out.println("hi, 我是 stone");
runnable.run();
()其实就是方法参数列表,这里没有传参数,那么就会去匹配无参的方法,因Runnable只有一个void run(),所以会匹配到它;这里没有写方法名,所以方法的名字会被忽略。
-> 这个后面跟方法体。这里只有一句打印代码,可以省略方法体的花括号:{} 。
注:这里还省略了”new Runnable”这样的代码,是因为编译器会进行自动的类型推断。如果直接调用 () -> System.out.println(“hi, 我是 stone”).run(); 那么是编译不过的,因为编译器不知道去哪个类里找对应的方法
有参数且有返回值的Lambda expression
代码:
button.setOnTouchListener((view, event)-> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (flag) {
return true;
}
}
return super.onTouchEvent(event);
});
有参数时,只要传参数名字即可,名字可随意定义;类型定义或不定义都可以;不定义时,编译器会自动推断。
有返回值时,可以在方法体中,使用return;也可以在只有一段代码时,省略return,如下:
button.setOnTouchListener((v, e) -> super.onTouchEvent(e));