tutorial mediante framework español desarrollo aplicaciones java lambda java-8 conceptual

mediante - java spring framework tutorial pdf



¿Por qué las referencias de métodos no son singleton? (3)

En Java, el siguiente código devuelve falso en ambas consultas. ¿Por qué? ¿No sería más simple que las referencias de métodos sean singleton? Sin duda, sería mucho más sencillo adjuntar y separar a los oyentes. Como es necesario, debe mantener una constante para cualquier referencia de método que deba verificarse con equivalencia, no puede usar el operador de referencia de método en cada ubicación necesaria.

public class Main { public Main() { // TODO Auto-generated constructor stub } public void doStuff() { } public static void main(String[] args) { Main main = new Main(); Runnable thing1 = main::doStuff; Runnable thing2 = main::doStuff; System.out.println(thing1 == thing2); // false System.out.println(thing1.equals(thing2)); // false } }


En este caso simple, podría hacer lo que sugiera al crear campos estáticos o de instancia adicionales según sea apropiado, más complejo si la lambda se refiere a objetos, sin embargo, la intención es hacer que estos casos queden fuera de existencia, por ejemplo.

List<String> list = .... list.stream().filter(s -> !s.isEmpty()).forEach(System.out::println);

Debería ser tan eficiente (incluso no crear más objetos que)

for (String s : list) if(!s.isEmpty()) System.out.println(s);

Puede eliminar los objetos al insertar el código de flujo y usar el análisis de escape para eliminar la necesidad de crear objetos en primer lugar.

Por esta razón, se ha prestado poca atención a la implementación de equals (), hashCode () o toString (), accediendo a ellos a través de la reflexión para los cierres. AFAIK, este deliberado para evitar que los objetos se utilicen de manera no intencionada.


Haciendo métodos singletons requerirá sincronizar la adquisición de una referencia a ellos. Esto le da una gran sobrecarga para una operación tan simple con un resultado impredecible. La otra solución es crear un objeto para cada método en la carga de clases, pero esto da como resultado muchos objetos redundantes, porque solo unos pocos métodos requieren referencia. Creo que la sincronización es el problema principal.


Por ejemplo , los métodos, no creo que tenga sentido que se almacenen en caché. Tendría que almacenar en caché un método por instancia ... lo que significaría un campo adicional dentro de la clase asociada con el método (uno por método público, probablemente, porque los métodos podrían ser referenciados desde fuera de la clase) o almacenados en caché dentro de la clase. usuario de la referencia del método, en cuyo caso necesitaría algún tipo de caché por instancia.

Creo que tiene más sentido que las referencias de métodos a métodos estáticos se almacenen en caché, ya que serán las mismas para siempre. Sin embargo, para almacenar en caché el Runnable real, necesitaría un caché por tipo al que se dirigía. Por ejemplo:

public interface NotRunnable { void foo(); } Runnable thing1 = Main::doStuff; // After making doStuff static NotRunnable thing2 = Main::doStuff;

¿Deberían thing1 y thing2 ser iguales aquí? ¿Cómo sabría el compilador qué tipo crear, si es así? Podría crear dos instancias aquí y guardarlas en caché por separado, y siempre guardarlas en el punto de uso en lugar del punto de declaración de método. (Su ejemplo tiene la misma clase que declara el método y hace referencia a él, lo cual es un caso muy especial. Debe considerar el caso más general en el que son diferentes>)

El JLS permite que las referencias de métodos se almacenen en caché. De la sección 15.13.3 :

A continuación, se asigna e inicializa una nueva instancia de una clase con las siguientes propiedades, o se hace referencia a una instancia existente de una clase con las siguientes propiedades.

... pero incluso para los métodos estáticos, parece que javac no hace ningún almacenamiento en caché en este momento.