【问题标题】:Detecting if a method is declared in an interface in Java检测是否在 Java 的接口中声明了方法
【发布时间】:2010-12-29 14:57:38
【问题描述】:

帮我把这个方法做得更扎实:

 /**
  * Check if the method is declared in the interface.
  * Assumes the method was obtained from a concrete class that 
  * implements the interface, and return true if the method overrides
  * a method from the interface.
  */
 public static boolean isDeclaredInInterface(Method method, Class<?> interfaceClass) {
     for (Method methodInInterface : interfaceClass.getMethods())
     {
         if (methodInInterface.getName().equals(method.getName()))
             return true;
     }
     return false;
 }

【问题讨论】:

  • 你可以有两个同名但参数不同的方法。
  • 为什么?这些信息会给你带来什么?
  • 为什么人们总是在这里坚持要知道“为什么”? :) 我只想通过 HTTP-GET 从 Hessian servlet 公开这些方法,并且我想过滤不相关的方法 - 通过接口过滤正是我需要的。
  • @ripper234,因为他们可能会针对原始问题提出更简单的解决方案。
  • 我们想知道为什么是因为从表面上看,它听起来有点倒退,而您的解释忽略了使情况并非如此所需的细节。例如,如果您知道接口并且知道您的对象实现了该接口,那么为什么不只从接口公开方法而不是从具体类公开方法呢?

标签: java reflection methods


【解决方案1】:

这个怎么样:

try {
    interfaceClass.getMethod(method.getName(), method.getParameterTypes());
    return true;
} catch (NoSuchMethodException e) {
    return false;
}

【讨论】:

  • 您不想将异常用作正常控制逻辑的一部分。
  • @Anon,通常不会,但如果这就是 API 给你的,那么你就在那里。如何判断一个 String 是否可以解析成 Integer?
  • 好久没用过Java了——C#为此提供了TryParse
  • 还需要捕获 SecurityException,尽管在这种情况下(拒绝访问包或方法),我不知道您是要返回 true 还是 false。如果拒绝访问包,则该方法可能存在也可能不存在。如果对方法的访问被拒绝,我很确定该方法存在但您无法访问它。
  • 是的,我在 java.net 上为 Integer.isInt(String) 方法争论了一段时间,但显然我是少数。
【解决方案2】:

如果您想避免从Yashai's answer 捕获NoSuchMethodException

for (Method ifaceMethod : iface.getMethods()) {
    if (ifaceMethod.getName().equals(candidate.getName()) &&
            Arrays.equals(ifaceMethod.getParameterTypes(), candidate.getParameterTypes())) {
        return true;
    }
}
return false;

【讨论】:

    【解决方案3】:

    这是一个好的开始:

    替换:

    for (Method methodInInterface : interfaceClass.getMethods())
     {
         if (methodInInterface.getName().equals(method.getName()))
             return true;
     }
    

    与:

    for (Method methodInInterface : interfaceClass.getMethods()) {
         if (methodInInterface.getName().equals(method.getName())) {
             return true;
         }
     }
    

    :)

    【讨论】:

      【解决方案4】:

      为了使您的方法更加健壮,您可能还想检查Class#isInterface() 是否为给定类返回true,否则抛出IllegalArgumentException

      【讨论】:

        【解决方案5】:

        查看Method#getDeclaringClass(),然后将 Class 对象与预期的接口进行比较。

        【讨论】:

        • 我认为您没有理解这个问题。我建议重新阅读问题和所有答案。
        • 当您在接口内部定义的方法上调用 getDeclaringClass() 时,结果将是实现类。所以这根本行不通。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-10
        • 2014-07-22
        • 1970-01-01
        • 2010-10-30
        相关资源
        最近更新 更多