【问题标题】:getDeclaredMethods() in Class classClass 类中的 getDeclaredMethods()
【发布时间】:2018-01-06 01:21:53
【问题描述】:
public Method[] getDeclaredMethods() throws SecurityException

有如下文档。

/**
     *
     * Returns an array containing {@code Method} objects reflecting all the
     * declared methods of the class or interface represented by this {@code
     * Class} object, including public, protected, default (package)
     * access, and private methods, but excluding inherited methods.

<p> If this {@code Class} object represents a type that has multiple
             * declared methods with the same name and parameter types, but different
             * return types, then the returned array has a {@code Method} object for
             * each such method.
         *

一个类怎么可能有两个 [已声明] 方法具有不同的返回类型、相同的名称和相同的参数类型?

【问题讨论】:

标签: java reflection


【解决方案1】:

Java 语言不可能声明两个具有相同名称和参数类型但返回类型不同的方法。

然而,Java 虚拟机 (JVM) 没有这样的处理方法。

有一种方法可以隐式创建此类方法,方法是用更具体的返回类型覆盖基类方法。

如果基类有一个方法 Object foo() 并且您的类用方法 String foo() 覆盖它,那么您的类的 .class 文件将有一个合成(因此不“可见”)方法 Object foo() 和一个“正常”的方法String foo()Object foo() 方法的存在是为了与希望将您的类视为基类实例并且不知道 String foo() 覆盖的类兼容。

此外,一些非 Java 语言可能允许您使用这些方法显式创建类。

【讨论】:

    【解决方案2】:

    一个简单的例子:

    import java.lang.reflect.Method;
    import java.util.concurrent.Callable;
    
    public class MultipleMethods implements Callable<String> {
        public static void main(String[] args) {
            for(Method m: MultipleMethods.class.getDeclaredMethods()) {
                System.out.println(m);
            }
        }
    
        @Override
        public String call() {
            return "just an example";
        }
    }
    

    Test on ideone.com

    public static void MultipleMethods.main(java.lang.String[])
    public java.lang.Object MultipleMethods.call() throws java.lang.Exception
    public java.lang.String MultipleMethods.call()
    

    由于类型擦除,接口Callable 有一个方法java.lang.Object call(),并且试图调用该方法的代码将仅查找该方法,因此,所谓的bridge method已插入以履行协议并委托给实际的实现方法String call()。您可以通过Method.isBridge() 识别桥接方法。

    this answer 所述,在不使用泛型的情况下使用covariant return types 时会创建相同类型的桥接方法。此外,正如这个答案已经说过的,类文件可能是通过 Java 源代码以外的其他方式创建的,并且由于 JVM 可以处理仅返回类型不同的方法,因此此类方法可能出现在此类类中而没有桥接语义。

    顺便说一句,在字节码级别,即使声明的字段也通过名称​​和类型来区分,因此,如果它们的类型不同,则不需要具有唯一的名称。没有办法生成与 Java 源代码具有相同名称的声明字段的类文件,但是,如上所述,这不是创建类文件的唯一方法。

    【讨论】:

      【解决方案3】:

      您可能会混淆 getDeclaredMethod() : MethodgetDeclaredMethods() : Method[]privateGetDeclaredMethods() : Method[],它们的名称不同。

      但是,您可以使用名称相同、返回类型相同但参数不同的方法。这是可能的,因为 Java 中的 method overloading


      为简单起见,这是一段非常合法的代码:

      public class Test {
          public int get(int a) {
              return a;
          }
      
          public int get() {
              return 0;
          }
      }
      

      这不是:

      public class Test {
          public int get() {
              return 0;
          }
      
          public long get() {
              return 0;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-30
        • 2011-05-04
        • 2022-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-20
        • 2020-01-16
        相关资源
        最近更新 更多