【问题标题】:Why doesn't my interface have the methods the JLS says it declares?为什么我的接口没有 JLS 声明的方法?
【发布时间】:2017-04-27 23:46:27
【问题描述】:

在 JLS 中阅读此 part

如果一个接口没有直接的超接口,则该接口隐式声明一个公共抽象成员方法 m,签名为 s,返回类型为 r,并且 throws 子句 t 对应于每个签名为 s,返回类型为 r 的公共实例方法 m,并且在 Object 中声明 throws 子句,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的方法。

我试图通过反射确认这些方法的存在,但只出现了ok方法。

为什么不显示隐式声明的方法?我怎样才能看到它们?

interface C {
    public void ok();
}
public class Test{
    public static void main(String[] args) {
        for (Method m : C.class.getMethods()) {
            System.out.println(m.getName()+":"+Modifier.isAbstract(m.getModifiers()));
        }
    }
}

输出:

ok:true

【问题讨论】:

  • 实例化一个C 实例,并查看它的方法。或者在 C 实例上调用 toStringC c = new SubC(); System.out.println(c.toString());
  • @ElliottFrisch:这并不能证明隐式 public abstract 方法声明的存在。
  • 我认为这要么是实现错误,要么是 JLS 缺陷。
  • @ElliottFrisch,我同意 user2357112 。如果我将代码应用于类,它将在 reflect.Methods 中打印 Object 方法

标签: java methods reflection language-lawyer


【解决方案1】:

JLS 是准确的,但您对 Class.getMethods() 返回的内容做出了错误假设:

返回一个包含 Method 对象的数组,该对象反映了此 Class 对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。

...

如果此Class 对象表示一个接口,则返回的数组不包含来自Object 的任何隐式声明的方法。因此,如果在此接口或其任何超接口中没有显式声明任何方法,则返回的数组的长度为 0。

【讨论】:

  • 一方面,是的,这是合理的。我忽略了文档的那部分。另一方面,Class.getDeclaredMethods 在其 Javadoc 中没有任何此类文本,但它显示了相同的行为(并且它在其输出中包含桥接方法,因此我希望这些方法也可以计算在内)。文档缺陷?我怀疑Class.getMethodClass.getDeclaredMethod 的行为是一样的,虽然我没有测试过。
  • @user2357112 Class.getDeclaredMethods() never 返回继承的方法,并且也清楚地记录在案:返回一个包含 Method 对象的数组,反映类的所有声明方法或此Class 对象表示的接口,包括公共、受保护、默认(包)访问和私有方法,但不包括继承方法。
  • 但是这些不是继承的。
  • 那么,我没有办法获取接口的所有方法吗?或者我可以假设每个接口都会隐式包含 Object 的方法(假设没有覆盖)。
  • 你可以分别从 Object 获取它们。
猜你喜欢
  • 2011-04-06
  • 2010-09-06
  • 2017-09-13
  • 2010-10-13
  • 1970-01-01
  • 2023-03-13
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多