Java interface de sintético geração método enquanto estreitando tipo de retorno

Roman Lebedev:

Eu tenho 2 interfaces, e 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>{}

Assim, em tempo de execução, eu posso 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()

Em relação à primeira, é sintético. (method.getModifiers() & 0x00001000 > 0) == true

Será java gerar automaticamente estes métodos sintéticos?

Como isso funciona em geral?

John Kuhn:

O que você vê aqui é chamado um método ponte.

Para entender por que isso é necessário, temos de olhar para a forma como a JVM determina se dois métodos são diferentes:

  • Cada método tem um nome. nome diferente -> método diferente.
  • Cada método tem um descritor. descritor- diferente> método diferente.

O descritor contém todos os argumentos e o tipo de retorno (com os genéricos, é apagamento).

Do ponto de vista JVM Flow doSomething()é um método diferente Publisher doSomething(), então quando ele é convidado a fazer uma chamada invokeinterface para Publisher doSomething()ele não vai chamar Flow doSomething().

Isso pode acontecer se o alvo no callsite é do tipo interfaceA:

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

Mas do ponto de vista da linguagem, ambos os métodos são os mesmos, e um substitui o outro.

Para restaurar essa relação, javacadiciona um método ponte com o tipo de método original que só chama o método sobrecarregado.

Acho que você gosta

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