Ответ 1
Если мы рассмотрим байт-код интерфейса TwoMethods, мы увидим, что фактический метод
public abstract method(Ljava/lang/Object;)V
то есть на уровне байт-кода информация о параметре типа не существует, тип стирается, JVM просто не знает о дженериках, параметры типа заменяются либо с помощью Object
, либо в случае, если T extends X
с X
. Итак, с точки зрения JVM
class A implements TwoMethods<A> {
public void method(A a) {
...
method(A a)
не переопределяет метод интерфейса, потому что в байт-коде, который он находится в method(Object obj)
, может переопределить его. Чтобы исправить эту проблему, компилятор строит неявный метод, так называемый метод bridge, в классе A
public void method(Object obj) {
method((A)obj);
}
отображается только в байтовом коде. Теперь для этого кода
A a = new A();
TwoMethods<A> tm = a;
tm.method(a);
компилятор заменит tm.method(a)
на вызов мосту
INVOKEINTERFACE test/TwoMethods.method(Ljava/lang/Object;)V
и это перенаправит вызов на A.method(A a);