Diferencia entre el método de referencia Receptor vinculado y Receptor no vinculado

Resuelto Harmeet Singh Taara asked hace 8 años • 7 respuestas

Estoy intentando utilizar referencias de métodos de Java 8 en mi código. Hay cuatro tipos de referencias de métodos disponibles.

  1. Referencia del método estático.
  2. Método de instancia (receptor vinculado).
  3. Método de instancia (receptor independiente).
  4. Referencia del constructor.

Con la referencia del método estático y la referencia del constructor no tengo ningún problema, pero el método de instancia (receptor vinculado) y el método de instancia (receptor independiente) realmente me confundieron. En el receptor vinculado , utilizamos una variable de referencia de objeto para llamar a un método como:

objectRef::Instance Method

En el receptor independiente utilizamos el nombre de clase para llamar a un método como:

ClassName::Instance Method.

Tengo la siguiente pregunta:

  1. ¿Cuál es la necesidad de diferentes tipos de referencias de métodos, por ejemplo, métodos?
  2. ¿Cuál es la diferencia entre encuadernado y no encuadernado ? las referencias de métodos de receptor
  3. ¿Dónde deberíamos usar el receptor vinculado y dónde deberíamos usar el receptor no vinculado ?

También encontré la explicación del receptor vinculado y no vinculado en los libros de características del lenguaje Java 8 , pero todavía estaba confundido con el concepto real.

Harmeet Singh Taara avatar Mar 10 '16 18:03 Harmeet Singh Taara
Aceptado

La idea del receptor independiente es que String::lengthte refieres a un método de un objeto que se proporcionará como uno de los parámetros de lambda . Por ejemplo, la expresión lambda (String s) -> s.toUpperCase()se puede reescribir comoString::toUpperCase .

Pero acotado se refiere a una situación en la que llamas a un método en una lambda a un objeto externo que ya existe . Por ejemplo, la expresión lambda () -> expensiveTransaction.getValue()se puede reescribir comoexpensiveTransaction::getValue .

Situaciones para tres formas diferentes de referencia de métodos

  • (args) -> ClassName.staticMethod(args) puede ser ClassName::staticMethod// Esto es estático (también puedes pensar como unBound)

  • (arg0, rest) -> arg0.instanceMethod(rest) puede ser ClassName::instanceMethod( arg0es de tipo ClassName) // Esto no está consolidado

  • (args) -> expr.instanceMethod(args) puede ser expr::instanceMethod// Esto está vinculado

Respuesta recuperada del libro Java 8 en acción

Johnny Willer avatar Mar 10 '2016 11:03 Johnny Willer

Básicamente, los receptores independientes le permiten usar métodos de instancia como si fueran métodos estáticos con un primer parámetro del tipo de declaración, por lo que puede usarlos como funciones pasando cualquier instancia que desee. Con un receptor vinculado, la instancia "destino" es efectivamente parte de la función.

Un ejemplo podría aclarar esto:

import java.util.function.*;

public class Test {

    private final String name;

    public Test(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Test t1 = new Test("t1");
        Test t2 = new Test("t2");

        Supplier<String> supplier = t2::method;
        Function<Test, String> function = Test::method;

        // No need to say which instance to call it on -
        // the supplier is bound to t2            
        System.out.println(supplier.get());

        // The function is unbound, so you need to specify
        // which instance to call it on
        System.out.println(function.apply(t1));
        System.out.println(function.apply(t2));
    }

    public String method() {
        return name;
    }
}
Jon Skeet avatar Mar 10 '2016 11:03 Jon Skeet

Cuando desea que el método se ejecute para una instancia específica de alguna clase, utiliza un receptor vinculado.

Por ejemplo :

Stream.of("x","y").forEach(System.out::println);

se ejecutará printlnen una instancia específica de PrintStream- la System.outinstancia. Por lo tanto System.out.println("x"), y System.out.println("y")se ejecutará como resultado de pasar esa referencia de método a forEach.

Por otro lado, si desea que el método se ejecute para una instancia no especificada de una clase, puede utilizar un receptor independiente.

Por ejemplo :

Stream.of("x","y","").filter(String::isEmpty);

se ejecutará isEmpty()en cada una de las Stringinstancias de Stream, es decir "x".isEmpty(), "y".isEmpty()y "".isEmpty().

Eran avatar Mar 10 '2016 11:03 Eran

Capturé esto de una presentación reciente.

ingrese la descripción de la imagen aquí

ZiglioUK avatar Dec 01 '2018 00:12 ZiglioUK