【问题标题】:Determining if a method overrides another using reflection? [duplicate]确定一个方法是否使用反射覆盖另一个方法? [复制]
【发布时间】:2013-02-22 10:18:16
【问题描述】:

这可能吗?

如果Class B 可从Class A 分配并且Method AMethod B 具有相同的签名,我发现的唯一解决方案通常认为方法被覆盖。但它并没有涵盖所有情况!

例如,我想处理这种情况:

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

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

我还想检查Method B 是否对Method A 实际可见(包范围等)。

您是否体验过一种可靠的方法来确定某个方法是否被覆盖?

谢谢

【问题讨论】:

  • 不要忘记@Overridable 可选注释。

标签: java reflection


【解决方案1】:

如果不涉及泛型,则有一个existing answer 来确定方法是否被覆盖。

由于type erasure,Java 将完全删除泛型类型。所以字节码是:

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 method。它只是进行类型转换并调用 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),它会报yes。

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

【讨论】:

  • 更新了答案。 @user1642427
  • 非常有帮助,感谢您的澄清!我将自己实现这一点,因为我没有找到任何能够做到这一点的库。如果它最终得到一个优雅而简短的解决方案,我会在这里发布。
  • 我刚刚在这里发布了我的解决方案(用 Kotlin 编写):stackoverflow.com/questions/4821704/…
猜你喜欢
  • 2012-08-21
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多