возвращаемый тип метода Java не является фактическим типом - PullRequest
0 голосов
/ 09 июня 2018

Тип возвращаемого значения метода Java не является фактическим типом.Например,

public interface Foo<X extends TypeA> {
    public X hello();
}

public class Bar implements Foo<TypeB> {
    @Override
    public TypeB hello() {
       ...
    }
}

Method method = Bar.class.getDeclaredMethod("hello");
Class returnType = method.getReturnType();

returnType равен TypeA, а не TypeB.TypeB является подклассом TypeA.

Как получить фактический тип возвращаемого значения метода?Это TypeB, а не TypeA.

ОБНОВЛЕНИЕ

Я использовал

Method[] methods = Bar.class.getDeclaredMethods();

, а затем перебирал методы.Метод возвращает суперкласс.Проверено, что getDeclaredMethod ("hello") действительно возвращает тип подкласса.Почему они разные?

1 Ответ

0 голосов
/ 09 июня 2018

Если вы выполните итерацию всех объявленных методов с помощью getDeclaredMethods(), вы найдете два метода с похожей подписью:

  • TypeB hello() (это тот, который вы ожидали)
  • TypeA hello() (это тот, о котором вы говорите)

Просмотр байт-кода показывает следующие записи:

public hello()Ltest/TypeB;

//... the bytecode for your method

public synthetic bridge hello()Ltest/TypeA;

//... bytecode that delegates to hello()Ltest/TypeB

Это эффект компилятора javac, который представляетсинтетический метод моста TypeA hello(), который делегирует только TypeB hello().

Причина в том, что виртуально может быть вызван только метод с одной и той же сигнатурой.Поскольку сигнатура интерфейса TypeA hello(), любой вызов интерфейса вызовет TypeA hello() в реализации.Тем не менее, ваш класс Bar не содержит этот метод, но заменяет TypeB hello().Чтобы решить эту проблему, javac решил соединить метод (делегировать его на замену).Я думаю, что это сэкономит им много работы во время выполнения.

Так что ваша проблема не в методе, возвращающем неправильный тип, а в том, что ваш код возвращает неправильный метод.Если вы выполняете итерацию методов, вызовите для них isSynthetic() (true означает, что это не интересующий метод).

...