学习笔记 : JDK 8新特性之方法引用
简介
当要传递给Lambda体的操作已经有实现的方法时,就可以使用方法引用
咯~ 方法引用可以看做是Lambda表达式深层的表达,换句话说 : 方法引用就是Lambda表达式,既函数式接口的一个实例,通过方法的名字来指定一个方法,可以认为是Lambda表达式的一个语法糖~
要求
实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
格式
使用操作符 ::
将类(或对象)与方法名分隔开来
语法
- 对象 :: 实例方法名
- 类 :: 静态方法名
- 类 :: 实例方法名
基本使用
下面通过一个简单的程序示例,来对比Lambda表达式与方法引用写法之间的区别 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package pers.huangyuhui.method;
import org.junit.Ignore; import org.junit.Test;
@FunctionalInterface interface Printable { void print(String s); }
public class methodTest {
public void printResult(String s, Printable printable) { printable.print(s); }
@Test public void testPrintString() { printResult("hello lambda", new Printable() { @Override public void print(String s) { System.out.println(s); } }); }
@Test public void testPrintStringWithLambda() { printResult("hello lambda", s1 -> System.out.println(s1)); }
@Test public void testPrintStringWithMethodRef() { printResult("hello lambda", System.out::println); } }
|
语义分析
例如上例中,System.out
对象中有一个重载的println(String)
方法恰好就是我们所需要的,那么对于printResult
方法的函数式接口参数,对比以下两种写法,完全等效 :
- Lambda表达式写法 :
s -> System.out.println(s)
- 方法引用写法 :
System.out::println
第一种语义是指 : 拿到参数之后,继而传递给System.out.println
方法去处理
第二种语义是指 : 直接让System.out
中的println
方法取代Lambda. 这种写法复用了已有方案,更加简洁
常用的几种方法引用
通过对象名引用成员方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package pers.huangyuhui.method;
import org.junit.Test;
@FunctionalInterface interface Printable { void print(String s); }
class Method { public void printUpperCaseStr(String s) { System.out.println(s.toUpperCase()); } }
public class RefMethodByObjTest {
public void printResult(String s, Printable printable) { printable.print(s); }
@Test public void testPrintResult() { printResult("hello lambda", new Printable() { @Override public void print(String s) { Method obj = new Method(); obj.printUpperCaseStr(s); } }); }
@Test public void testPrintResultWithLambda() { printResult("hello lambda", s -> { Method obj = new Method(); obj.printUpperCaseStr(s); }); }
@Test public void testPrintResultWithMethodRef() { Method obj = new Method(); printResult("hello lambda", obj::printUpperCaseStr); } }
|
通过类名引用静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package pers.huangyuhui.method;
import org.junit.Test;
@FunctionalInterface interface calculable { int add(int x, int y); }
class Method { public static int add(int x, int y) { return x + y; } }
public class RefStatisMethodByClazzName {
public int getResult(int x, int y, calculable calculable) { return calculable.add(x, y); }
@Test public void testGetResult() { int result = getResult(1, 2, new calculable() { @Override public int add(int x, int y) { return Method.add(x, y); } }); System.out.println(result); }
@Test public void testGetResultWithLambda() { int result = getResult(1, 2, (x, y) -> Method.add(x, y)); System.out.println(result); }
@Test public void testGetResultWithMethodRef() { int result = getResult(1, 2, Method::add); System.out.println(result); } }
|
通过Supper引用父类中的成员方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package pers.huangyuhui.method;
import org.junit.Test;
@FunctionalInterface interface Agreeable { void greet(); }
class Human { public void hello() { System.out.println("hello my sun !"); } }
public class RefMethodBySupper extends Human {
@Override public void hello() { System.out.println("hello my father !"); }
public void printResult(Agreeable agreeable) { agreeable.greet(); }
@Test public void testPrintResult() { printResult(new Agreeable() { @Override public void greet() { RefMethodBySupper.super.hello(); } }); }
@Test public void testPrintResultWithLambda() { printResult(() -> super.hello()); }
@Test public void testPrintResultWithMethodRef() { printResult(super::hello); }
}
|
通过this引用成员方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package pers.huangyuhui.method;
import org.junit.Test;
@FunctionalInterface interface Supermarket { void buy(); }
public class RefMethodByThis {
public void buyLaptop() { System.out.println("buy a laptop successfully"); }
public void printResult(Supermarket supermarket) { supermarket.buy(); }
@Test public void testPrintResult() { printResult(new Supermarket() { @Override public void buy() { buyLaptop(); } }); }
@Test public void testPrintResultWithLambda() { printResult(() -> this.buyLaptop()); }
@Test public void testPrintResultWithMethodRef() { printResult(this::buyLaptop); }
}
|
类的构造器引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package pers.huangyuhui.method;
import org.junit.Test;
@FunctionalInterface interface UserBuilder { User builder(String name); }
class User { private String name;
public User(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public class RefConstructor {
public void printResult(String name, UserBuilder userBuilder) { User user = userBuilder.builder(name); System.out.println(user.getName()); }
@Test public void testPrintResult() { printResult("yubuntu0109", new UserBuilder() { @Override public User builder(String name) { return new User(name); } }); }
@Test public void testPrintResultWithLambda() { printResult("yubuntu0109", s -> new User(s)); }
@Test public void testPrintResultWithMethodRef() { printResult("yubuntu0109", User::new); }
}
|
数组的构造器引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package pers.huangyuhui.method;
import org.junit.Test;
import java.util.Arrays;
@FunctionalInterface interface ArrayBuilder { int[] builderArray(int length); }
public class RefArrayConstructor {
public static int[] getArray(int length, ArrayBuilder arrayBuilder) { return arrayBuilder.builderArray(length); }
@Test public void testgetArray() { int[] array = getArray(10, new ArrayBuilder() { @Override public int[] builderArray(int length) { return new int[length]; } }); System.out.println(Arrays.toString(array)); }
@Test public void testArrayWithLambda() { int[] array = getArray(10, length -> new int[length]); System.out.println(Arrays.toString(array)); }
@Test public void testArrayWithMethodRef() { int[] array = getArray(10, int[]::new); System.out.println(Arrays.toString(array)); } }
|