如何判断类中的方法是否在实现的接口中声明?
如何判断类中的方法是自身声明还是来自接口实现
要区分类中声明的方法和实现接口的方法,不能仅依赖getDeclaringClass()——因为重写接口的方法会被标记为类自身声明的。可以通过以下两种方式实现:
方法一:使用Java 11+的Method.overrides()方法
Java 11新增的overrides(Method other)方法可以直接判断当前方法是否重写了传入的接口方法,代码示例如下:
import java.lang.reflect.Method; public class Main { public static void main(String[] args) { Class<?> clazz = AClass.class; // 获取类实现的所有接口 Class<?>[] interfaces = clazz.getInterfaces(); for (Method classMethod : clazz.getDeclaredMethods()) { boolean isFromInterface = false; // 遍历每个接口的方法 for (Class<?> iface : interfaces) { for (Method ifaceMethod : iface.getDeclaredMethods()) { if (classMethod.overrides(ifaceMethod)) { isFromInterface = true; break; } } if (isFromInterface) break; } System.out.println("方法名: " + classMethod.getName()); System.out.println("是否为类自身声明: " + !isFromInterface); System.out.println(); } } }
方法二:手动判断(兼容Java 11以下版本)
如果使用低版本Java,需要手动校验方法签名的兼容性(包括协变返回类型):
- 方法名称必须相同
- 参数列表必须完全一致
- 类方法的返回类型可以是接口方法返回类型的子类/实现类(协变)
- 类必须实现该接口
代码示例:
import java.lang.reflect.Method; import java.lang.reflect.Parameter; public class Main { public static void main(String[] args) { Class<?> clazz = AClass.class; Class<?>[] interfaces = clazz.getInterfaces(); for (Method classMethod : clazz.getDeclaredMethods()) { boolean isFromInterface = false; for (Class<?> iface : interfaces) { for (Method ifaceMethod : iface.getDeclaredMethods()) { if (isOverride(classMethod, ifaceMethod)) { isFromInterface = true; break; } } if (isFromInterface) break; } System.out.println("方法名: " + classMethod.getName()); System.out.println("是否为类自身声明: " + !isFromInterface); System.out.println(); } } private static boolean isOverride(Method classMethod, Method ifaceMethod) { // 方法名必须相同 if (!classMethod.getName().equals(ifaceMethod.getName())) { return false; } // 参数列表必须一致 Parameter[] classParams = classMethod.getParameters(); Parameter[] ifaceParams = ifaceMethod.getParameters(); if (classParams.length != ifaceParams.length) { return false; } for (int i = 0; i < classParams.length; i++) { if (!classParams[i].getType().equals(ifaceParams[i].getType())) { return false; } } // 检查返回类型协变:类方法返回类型是接口方法返回类型的子类/实现类 return ifaceMethod.getReturnType().isAssignableFrom(classMethod.getReturnType()); } }
输出结果
两种方法运行后都会输出:
方法名: hi 是否为类自身声明: false
这说明hi()方法是实现自接口的,并非AClass自身声明的方法。
内容的提问来源于stack exchange,提问作者Derek Li
相关产品推荐
相关产品推荐

