Usando el método de instancia en java 8 :: referencia de método con objeto nulo

¿Por qué cuando se usa un método de instancia en el método reference ( ::) no se arroja a NullPointerExceptionsi establecemos la instancia de Object en null?

  public class MethodReferenceTest {

        public static void main(String...strings){

            PredicateSample predicateSample = new PredicateSample();
            Predicate<String> predicate = predicateSample::isNotEmpty;
            // NullpointerException ???
            predicateSample = null;
            Arrays.asList("a","b","c",null)
                .stream()
                .filter(predicate)
                .forEach(System.out::println);
        }

        static class PredicateSample{
            public boolean isNotEmpty(String s){
                return ((s!=null) && (!s.isEmpty()));
            }
        }
    }

Parece que predicateSampleno se invoca después de construir el predicado?

Respuesta 1

La línea clave en la especificación del lenguaje es donde se está discutiendo la evaluación en tiempo de ejecución de las referencias de métodos (énfasis mío):

  • Si el formulario es ExpressionName :: [TypeArguments] Identifier o Primary :: [TypeArguments] Identifier ...

    • ....
    • La referencia de destino es el valor de ExpressionName o Primary, según lo determinado cuando se evaluó la expresión de referencia del método .

Por lo tanto, no importa si cambia el valor de la referencia objetivo después.

Respuesta: 2

La referencia del método "recordó" el estado de predicateSamplecuando se inicializó. Tiene una referencia exactamente a la que new PredicateSample()ha creado antes.

Después de 2 líneas ejecutadas, tiene dos referencias a eso new PredicateSample(): la predicateSampley la "dentro" de la referencia del método.

Cambiar el primero no tiene ningún efecto para el segundo.


Hagamos un truco interesante.

Aquí hay una matriz para envolver un new PredicateSample()en un predicates[0]:

PredicateSample[] predicates = new PredicateSample[1];
predicates[0] = new PredicateSample();

Dentro de la lambda, utiliza una referencia a predicates[0];

Predicate<String> predicate = string -> predicates[0].isNotEmpty(string);

Actualizar el predicates[0]al nully hacer las mismas cosas:

predicates[0] = null;
Stream.of("a","b","c").filter(predicate).forEach(System.out::println);
Respuesta: 3

¿Cómo puedo crear un paquete de tiempo de ejecución de algún tipo, un jar todo en uno con la clase Main especificada, un Mac .app o similar, a partir de un proyecto Eclipse Java? Me gustaría obtener todos los frascos necesarios ...

¿Hay algún tipo de datos en Java que almacene un número decimal con mayor precisión que un doble?

AH! Tengo una lista de cadenas ... y solo quiero eliminar un elemento de la lista si es "" pero sigo causando que el programa se bloquee. ¿Cómo puedo evitar esto? Hice una lista de matrices en una lista ...

¿Cómo se asegura el entorno Java cuando se ejecuta en una máquina que no controla? Qué es evitar que alguien cree un agente de Java o un agente JVMTI nativo y descarte el bytecode o reescriba ...