Método de referencia no parece siempre a instancia de captura

podómetro:

Sé que hay muchas preguntas sobre el tema, incluso una muy reciente , pero todavía no pueden trabajar mi cabeza alrededor de una cosa. Considere la siguiente interfaz funcional :

@FunctionalInterface
interface PersonInterface {
    String getName();
}

Y esta aplicación:

class Person implements PersonInterface {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Si miro a estos hilos 1 y 2 , espero que el siguiente código a la salida "Bob"y no tiro un NullPointerExceptionporque por lo que yo entiendo, cuando creo mi Proveedor, captura la Personinstancia.

Person p = new Person("Bob");
Supplier<String> f = p::getName;
p = null;
System.out.println(f.get());

Y correctamente salidas "Bob"

Ahora lo que no entiendo es por qué el siguiente código no lo hace también la salida "Bob"?

Person p = new Person("Bob");
Supplier<String> f = p::getName;
p.setName("Alice");
System.out.println(f.get());

En realidad, las salidas "Alice"

Me parece que en el primer ejemplo, el lambda capturó el estado del objeto persona cuando fue creado y no intenta volver a evaluar cuando se le llama, cuando en el segundo caso, parece que no capturarlo revalúa, pero cuando se le llama.

EDITAR Después de volver a leer los otros hilos y con la respuesta de Eran, escribí que poco con 2 personas apuntando a la misma instancia:

Person p1 = new Person("Bob");
Person p2 = p1;
Supplier<String> f1 = p1::getName;
Supplier<String> f2 = p2::getName;
p1 = null;
p2.setName("Alice");
System.out.println(f1.get());
System.out.println(f2.get());

Ahora puedo ver que tanto la salida "Alice"a pesar de que p1 es nulo y por lo tanto la referencia al método capturó la instancia sí mismo, no su estado como asumí erróneamente.

Eran :

Me parece que en el primer ejemplo, el lambda capturó el estado del objeto persona cuando fue creado y no intenta volver a evaluar cuando se le llama, cuando en el segundo caso, parece que no capturarlo revalúa, pero cuando se le llama.

En primer lugar, se trata de un método de referencia, no una expresión lambda.

En ambos casos una referencia a la Personinstancia es capturado por el método de referencia (que no es "el estado del objeto Person"). Eso significa que si el estado de la Personestá mutado ejemplo, el resultado de ejecutar el método de la interfaz funcional pueden cambiar.

La referencia método no crea una copia de la Personinstancia cuya referencia se captura.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=127274&siteId=1
Recomendado
Clasificación