Entenda o uso de dois pontos "::" em Java8, caractere de referência de método

Ao usar expressões lambda, o código que realmente passamos é uma solução: o que fazer com quais parâmetros. Imagine que existe tal situação: o esquema de operação que especificamos no Lambda já possui o mesmo esquema, então é necessário reescrever a lógica?

Claro que você não precisa. Neste momento, o que vamos explicar hoje é usado: o caractere de referência do método Java "::".

// Lambda 表达式写法:
s -> System.out.println(s);
// :: 方法引用写法:
System.out::println

Podemos usar o esquema existente por meio de referências de métodos para tornar as expressões mais concisas.


texto

Em Java 8, os dois pontos :: são chamados de "operador de referência de método", o símbolo :: é um operador de referência, e a expressão na qual ele está localizado é chamada de referência de método, e podemos usá-lo para fazer referência a um método de uma classe.

:: refere-se a um método de uma classe e retorna uma interface de função ( function interface ), que é equivalente a uma expressão lambda, mas diferente de uma expressão lambda, uma expressão lambda precisa personalizar um corpo lambda, enquanto :: se refere a um método.

/**
* 表示接受一个参数并生成结果的函数。
* @param<T>函数的输入类型
* @param<R>函数结果的类型
* @从1.8开始
*/
@FunctionalInterface
public interface Function<T, R> {
     R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

Existem quatro tipos de operadores de referência de método:

  1. ClassName :: New : uma referência ao construtor, equivalente a criar um objeto;
  2. ClassName :: static_method : Se houver parâmetros, os parâmetros serão usados ​​como os parâmetros reais do método;
  3. ClassName :: instance_method : O primeiro parâmetro é usado como um objeto de classe para chamar instance_method, e outros parâmetros são usados ​​como parâmetros de método;
  4. instance :: instance_method : Se houver parâmetros, os parâmetros serão usados ​​como os parâmetros reais do método;

caso

Abaixo, uma breve demonstração do uso dos quatro tipos de referências Java:

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Supplier;

/** 引用操作符的四种类型 */
public class JavaTest {

    public static class User {
        private String id;
        private Integer age;
        private String name;

        // ... 省略了参数的get(),set()方法

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("User{");
            sb.append("id='").append(id).append('\'');
            sb.append(", age=").append(age);
            sb.append(", name='").append(name).append('\'');
            sb.append('}');
            return sb.toString();
        }

        public static void testStatic(String s){
            System.out.println(s);
        }
    }

    /**
     * 1.构造器引用
     *   ClassName::New => new ClassName()
     *   如果调用时有参数,相当于调用带参的构造函数
     */
    @Test
    public void test1(){
        App.toString(User::new);
    }
    public static void toString(Supplier supplier){
        System.out.println(supplier.get().toString());
    }

    /**
     * 2.静态方法引用
     *   ClassName::static_method =》 CLassName.static_method()
     *   如果调用时有参数,直接放到静态方法的形参中
     */
    @Test
    public void test2(){
        Arrays.asList("name1","name2").stream().forEach(User::testStatic);
    }

    /**
     * 3.特定类对方法引用
     *   ClassName::instance_method => obj.instance_method(xxx)
     *   调用时参数:第一个参数是实体对象 上面的obj
     *   如果有其他参数,会传到方法中
     */
    @Test
    public void test3(){
        User user = new User();
        user.setId("625");
        user.setAge(30);
        user.setName("java punk");
        Optional.of(user).ifPresent(User::toString);
    }

    /**
     * 4.特定对象对方法引用
     *   instance::instance_method =》instance.instance_method(xxxx);
     *   如果有参数,参数就是方法的参数
     */
    @Test
    public void test4(){
        User user = new User();
        user.setId("625");
        user.setAge(30);
        user.setName("java punk");
        toString(user::toString);
    }
}

Acho que você gosta

Origin blog.csdn.net/weixin_44259720/article/details/122680270
Recomendado
Clasificación