Java8——方法引用

Wesley13
• 阅读 481

方法引用就是通过类名或方法名引用已经存在的方法来简化lambda表达式。那么什么时候需要用方法引用呢?如果lamdba体中的内容已经有方法实现了,我们就可以使用方法引用。

一、方法引用的三种语法格式

1. 对象::实例方法名

lamdba写法:

@Test
void test1(){
    Consumer<String> con = x -> System.out.println(x);
}

方法引用写法:

@Test
void test2(){
    PrintStream out = System.out;
    Consumer<String> con = out::println;
}

consumer接口:

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

2. 类::静态方法名

lamdba写法:

@Test
void test3(){
    Comparator<Integer> com = (x, y) -> Integer.compare(x,y);
}

方法引用写法:

@Test
void test4(){
    Comparator<Integer> com = Integer::compare;
}

Comparator接口:

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

Integer类部分内容:

public final class Integer extends Number implements Comparable<Integer> { 
    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
}

注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

3. 类::实例方法名

lamdba写法:

@Test
void test5(){

    BiPredicate<String,String> bp = (x,y) -> x.equals(y);
}

方法引用写法:

@Test
void test6(){
    BiPredicate<String,String> bp = String::equals;
}

BiPredicate接口:

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);
}

注意:第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数时,就可以使用这种语法。

二、构造器引用

类::new

lamdba写法:

@Test
void test7(){
    Supplier<Person> supplier = ()->new Person();
}

构造器引用写法:

@Test
void test8(){
    Supplier<Person> supplier = Person::new;
}

Supplier接口:

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Person类:

@Data
public class Person implements Serializable {
    private static final long serialVersionUID = -7008474395345458049L;

    private String name;
    private int age;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

注意:person类中有两个构造器,要调用哪个构造器是函数式接口决定的,也就是Supplier接口中的get()方法是无参的,那么就调用的是person中的无参构造器。

三、数组引用

Type::new

lamdba写法:

@Test
void test9(){
    Function<Integer,String[]> fun = x -> new String[x];
}

数组引用写法:

@Test
void test10(){
    Function<Integer, String[]> fun = String[]::new;
}

Function接口部分内容:

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

总结

  • 方法应用及构造器引用其实可以理解为lamdba的另一种表现形式
  • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
  • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
  • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致
点赞
收藏
评论区
推荐文章
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java中多态的实现机制
多态的概念:  简单来说就是事物在运行过程中存在的不同状态,即父类或接口定义的引用变量指向子类或具体实现类的实例对象。程序调用方法在运行期才进行动态绑定,而不是引用变量的类型中定义的方法。多态存在的前提:1、存在继承关系,子类继承父类;2、子类重写父类的方法;3、父类引用指向子类对象。具体实例:1、定义一个父类:Animal
待兔 待兔
3年前
Java多态实现原理
Java多态概述多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定。Java对于方法调用动态绑定的实现主要依赖于方法表,但通过类引用调用(invokevirtual)和接口引用调用(invokeinterface)的实现则有所不同。类引用调用的大致过程为:Java编译器将Java源代码编译成c
Wesley13 Wesley13
3年前
Java8特性
Java8又称jdk1.8。主要新特性:Lambda表达式 −Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。方法引用 −方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
Wesley13 Wesley13
3年前
Java中
javacclasspath的使用:javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上classpath参数,通过使用以下三种类型的方法来指导编译器在编译的时候去指定的路径下查找引用类。(1).绝对路径:javac
Wesley13 Wesley13
3年前
Java8—一万字的Lambda表达式的详细介绍与应用案例
  基于Java8详细介绍了lambda表达式的语法与使用,以及方法引用、函数式接口、lambda复合等Java8的新特性!文章目录1Lambda的概述2函数式接口2.1Consumer消费型接口2.2Supplier供给型接口2.3Function<T,R函数型接口
Stella981 Stella981
3年前
GC roots
<divid"cnblogs\_post\_body"class"blogpostbody"<p1.虚拟机栈(本地变量表)引用的对象</p<div2.方法区静态属性引用的对象</div<div3.方法区常量引用的对象</div<div4.本地方法栈JNI(一般指naive方法)中引用的对象</div<div&nbsp;<
Wesley13 Wesley13
3年前
Java8 方法引用的使用
一、方法引用分类1.构造函数2.静态方法3.实例方法(类型)4.实例方法(对象)二、方法引用构造函数ClassName::new,示例:/@authorKevin@date20170124/pub
Wesley13 Wesley13
3年前
Java之关于This的用法
      用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该有一个引用来访问自己的属性和方法纳?呵呵,JAVA提供了一个很好的东西,就是this对象,它可以在类里面来引用这个类的属性和方法。先来个简单的例子:public class ThisDemo {   
Stella981 Stella981
3年前
JVM学习第二天
引用计数算法对象中添加一个引用计数,一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减一两对象互相引用,就会造成死循环,无法回收可达性分析算法通过GCRoots作为起点,向下搜索,到达不了的对象,即证明对象不可用GCRoots包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用