有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否使用反射确定一个方法是否覆盖另一个?

这可能吗

<> p>惟一的解决方案通常认为,如果{{CD1>}可从^ {CD2>}分配,并且如果^ {< CD3>}具有与^ {CD4>}相同的签名,则该方法被重写。但它并不是涵盖所有案例

例如,我想处理这个案件:

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

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

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

您是否曾经使用过可靠的方法来确定某个方法是否被重写

多谢各位


共 (1) 个答案

  1. # 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
    }
    

    有两种方法。这是一个bridge method。它只需输入cast并调用void doStuff(java.lang.String),因此实际上void doStuff(java.lang.String)不会被覆盖,而void doStuff(java.lang.Object)是。当您使用多态性时,例如:

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

    它实际上调用voiddostuff(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