Подтвердить что ты не робот

Определение того, что метод переопределяет другой, используя отражение?

Возможно ли это?

Единственные найденные решения обычно рассматривают метод как переопределенный, если Class B можно назначить из Class A, а если Method A имеет ту же подпись, что и Method B. Но это не распространяется на все случаи!

Например, я хочу обработать этот случай:

interface Foo<T> {
    void doStuff(T arg);    
}

class FooImpl implements Foo<String> {
    public void doStuff(String args) {
        //Is overriden!  
    }
}

Я также хочу проверить, что Method B на самом деле отображается Method A (область пакета и т.д.).

Вы когда-нибудь испытывали надежный метод определения того, переопределен ли метод?

Спасибо

4b9b3361

Ответ 1

Существует существующий ответ, чтобы определить, переоценивается ли метод, если нет никаких генериков.

Java полностью удалит общий тип из-за типа erasure. Таким образом, байт-код будет:

class FooImpl implements Foo<java.lang.String> {
  FooImpl();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: return

  public void doStuff(java.lang.String);
    Code:
       0: return

  public void doStuff(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #21                 // class java/lang/String
       5: invokevirtual #23                 // Method doStuff:(Ljava/lang/String;)V
       8: return
}

Существует два метода doStuff. Это метод bridge. Это просто тип cast и invoke void doStuff (java.lang.String), поэтому на самом деле void doStuff (java.lang.String) не переопределяется, но void doStuff (java.lang.Object). Когда вы используете полиморфизм, например:

Foo foo = new FooImpl();
foo.doStuff("ABC")

На самом деле он называет void doStuff (java.lang.Object). Поэтому, если вы используете указанную выше ссылку, чтобы определить, превышен ли void doStuff (java.lang.Object), она сообщит "да".

public static void main(java.lang.String[]);
    Code:
       0: new           #1                  // class FooImpl
       3: dup
       4: invokespecial #22                 // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: ldc           #23                 // String ABC
      11: invokeinterface #25,  2           // InterfaceMethod Foo.doStuff:(Ljava/lang/Object;)V
      16: return