Java generación método de interfaz sintético, mientras que la reducción de tipo de retorno

Romano Lebedev:

Tengo 2 interfaces, y 2 tipos de retorno.

interface interfaceA {
   Publisher<String> doSomething();
}

interface interfaceB extends interfaceA {
   Flow<String> doSomething();
}

interface Publisher<T>{}
class Flow<T> implements Publisher<T>{}

Por lo tanto en tiempo de ejecución, puedo ver 2 métodos de interfaceB.class.getMethods()

  1. public default my.package.Publisher my.package.interfaceB.doSomething()

  2. public abstract my.package.Flow my.package.interfaceB.doSomething()

En cuanto a la primera, que es sintético. (method.getModifiers() & 0x00001000 > 0) == true

Java no autogenerar estos métodos sintéticos?

¿Cómo funciona en general?

John Kuhn:

Lo que se ve aquí se llama un método puente.

Para entender por qué esto es necesario, tenemos que buscar la forma de la JVM determina si dos métodos son diferentes:

  • Cada método tiene un nombre. nombre diferente -> método diferente.
  • Cada método tiene un descriptor. Diferentes descriptor-> método diferente.

El descriptor contiene todos los argumentos y el tipo de retorno (con los genéricos, es borrado).

Desde la perspectiva de JVM Flow doSomething()es un método diferente que Publisher doSomething(), por lo que cuando se le pide que haga una llamada a invokeinterface Publisher doSomething()no va a llamar Flow doSomething().

Esto puede suceder si el objetivo en el callsite es de tipo interfaceA:

intefaceA foo = ...;
foo.doSomething();

Pero desde el punto de vista del lenguaje, ambos métodos son los mismos, y uno prevalece sobre el otro.

Para restaurar esta relación, javacañade un método de puente con el tipo de método original que simplemente llama al método sobrecargado.

Supongo que te gusta

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