java8新特性:二,方法引用
方法引用(method reference)通过方法的名字来指向一个方法。
方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
方法引用使用一对冒号 :: 。
1 函数式接口@FunctionalInterface
@FunctionalInterface
interface Supply<T>{
T get();
}
查看源码:
从概念上讲,函数式接口只有一个抽象方法。
函数式接口的实例可以以lambda表达式,方法引用或者构造函数引用来创建。
以这个注解来注释的类型,除非是接口,并且还不是注解、枚举或者类,否则编译器需要报错
然而,编译器会将任何达到函数式接口定义的接口视为函数式接口,无论接口中是否声明了@FunctionalInterface
函数式接口有一个以上抽象方法时,编译器会报错
或者修饰非接口,如枚举等,也会编译器报错
2 方法引用
public class Refe {
public static Refe create(final Supply<Refe> s){
return s.get();
}
public static void one(final Refe r){
System.out.println("one:"+r.toString());
}
public void two(final Refe r2){
System.out.println("two:"+r2.toString());
}
public void three(){
System.out.println("three:"+this.toString());
}
public static void main(String[] args) {
}
}
@FunctionalInterface
interface Supply<T>{
T get();
}
2.1 构造器引用
import java.util.Arrays;
import java.util.List;
public class Refe {
public static Refe create(final Supply<Refe> s){
return s.get();
}
public static void one(final Refe r){
System.out.println("one:"+r.toString());
}
public void two(final Refe r2){
System.out.println("two:"+r2.toString());
}
public void three(){
System.out.println("three:"+this.toString());
}
public static void main(String[] args) {
//构造器引用 它的语法是Class::new,或者更一般的Class< T >::new
final Refe r1=Refe.create(Refe::new);
System.out.println(r1);
final List<Refe> feres= Arrays.asList(r1);
System.out.println(feres);
}
}
@FunctionalInterface
interface Supply<T>{
T get();
}
将1个元素转换成集合,可以使用Collections.singletonList(对象),不需要使用Arrays.asLIst(对象)来转换成集合
import java.util.Collections;
import java.util.List;
public static void main(String[] args) {
//构造器引用 它的语法是Class::new,或者更一般的Class< T >::new
final Refe r1=Refe.create(Refe::new);
System.out.println(r1);
final List<Refe> feres= Collections.singletonList(r1);
System.out.println(feres);
}
2.2 静态方法引用
public static void main(String[] args) {
//构造器引用 它的语法是Class::new,或者更一般的Class< T >::new
final Refe r1=Refe.create(Refe::new);
System.out.println(r1);
final List<Refe> feres= Collections.singletonList(r1);
System.out.println(feres);
//静态方法引用 它的语法是Class::static_method
feres.forEach(Refe::one);
}
2.3 特定类的任意对象的方法引用
public static void main(String[] args) {
//构造器引用 它的语法是Class::new,或者更一般的Class< T >::new
final Refe r1=Refe.create(Refe::new);
System.out.println(r1);
final List<Refe> feres= Collections.singletonList(r1);
System.out.println(feres);
//静态方法引用 它的语法是Class::static_method
feres.forEach(Refe::one);
//特定类的任意对象的方法引用 它的语法是Class::method
feres.forEach(Refe::three);
}
2.4 特定对象的方法引用
public static void main(String[] args) {
//构造器引用 它的语法是Class::new,或者更一般的Class< T >::new
final Refe r1=Refe.create(Refe::new);
System.out.println(r1);
final List<Refe> feres= Collections.singletonList(r1);
System.out.println(feres);
//静态方法引用 它的语法是Class::static_method
feres.forEach(Refe::one);
//特定类的任意对象的方法引用 它的语法是Class::method
feres.forEach(Refe::three);
//特定对象的方法引用 它的语法是instance::method
final Refe r2=Refe.create(Refe::new);
feres.forEach(r2::two);
}
2.5 换个版本
import java.util.Collections;
import java.util.List;
public class Fr {
public static Fr create(Supply<Fr> x){
return x.mytry();
}
public void one(){
System.out.println("one:"+this.toString());
}
public void two(Fr k){
System.out.println("two:"+k.toString());
}
public static void three(Fr l){
System.out.println("three:"+l.toString());
}
public static void main(String[] args) {
Fr f=create(Fr::new);
System.out.println(f);
List<Fr> l= Collections.singletonList(f);
System.out.println(l);
l.forEach(Fr::three);
l.forEach(Fr::one);
Fr g=Fr.create(Fr::new);
l.forEach(g::two);
}
}
@FunctionalInterface
interface Supply<T> {
T mytry();
}
3.1 方法引用实例
import java.util.ArrayList;
import java.util.List;
public class Frr {
public static void main(String[] args) {
List<String> l=new ArrayList(){{
add("xiaoxu");
add("nihao");
}};
System.out.println(l);
l.forEach(System.out::println);
}
}
查看System.out的println方法源码:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
3.2 静态方法引用实例
public class Frr {
public static void main(String[] args) {
Yu y=new Yu(){
@Override
public int s(int a,int b){
return a+b;
}
};
System.out.println(y.s(12, 45));
Yu u=Integer::sum;
System.out.println(u.s(12,45));
}
}
interface Yu{
int s(int a,int b);
}
57
57
查看Interger的sum方法源码(静态方法):
public static int sum(int a, int b) {
return a + b;
}
补充:
//匿名内部类实例化接口,必须重写全部的方法,并且重写的方法权限修饰符必须带上public
public class XiXin {
public static void main(String[] args) {
Try a=new Try(){
@Override
public void run(){
System.out.println("你好");
}
@Override
public void eat() {
System.out.println("我好");
}
};
a.eat();
a.run();
}
}
interface Try{
void run();
public void eat();
}