如何检查Java反射Method对象是否带有@Override注解?
检查方法是否对应@Override标记的可行方案
首先明确:@Override注解的保留级别是SOURCE,编译后不会被保留在字节码中,所以不管用method.isAnnotationPresent(Override.class)还是MergedAnnotations,都没法直接检测到它的存在。
要判断一个方法是不是原本被标记了@Override的重写方法,得换个思路——从方法是否真的重写了父类或接口的方法来判断,因为@Override本身就是用来校验这一点的。下面是两种可行的实现方式:
方式一:校验父类/接口中是否存在同签名方法
直接遍历当前方法的声明类的父类和实现的接口,看有没有匹配签名的方法:
public static boolean isOverriddenMethod(Method method) { Class<?> declaringClass = method.getDeclaringClass(); // 检查所有父类 for (Class<?> superClass = declaringClass.getSuperclass(); superClass != null; superClass = superClass.getSuperclass()) { try { superClass.getMethod(method.getName(), method.getParameterTypes()); return true; } catch (NoSuchMethodException e) { // 父类没这个方法,继续往上找 } } // 检查所有实现的接口 for (Class<?> iface : declaringClass.getInterfaces()) { try { iface.getMethod(method.getName(), method.getParameterTypes()); return true; } catch (NoSuchMethodException e) { // 接口没这个方法,换下一个 } } return false; }
只要父类或接口里能找到相同签名的方法,就说明这个方法是重写方法,对应原本的@Override标记。
方式二:兼容泛型桥接方法
如果是泛型相关的桥接方法,它本身可能没写@Override,但实际是重写父类的泛型方法。可以结合isBridge()来完善判断:
public static boolean isOverriddenMethod(Method method) { // 桥接方法本身就是为了泛型重写生成的,直接返回true if (method.isBridge()) { return true; } // 复用上面的父类和接口检查逻辑 Class<?> declaringClass = method.getDeclaringClass(); for (Class<?> superClass = declaringClass.getSuperclass(); superClass != null; superClass = superClass.getSuperclass()) { try { superClass.getMethod(method.getName(), method.getParameterTypes()); return true; } catch (NoSuchMethodException e) {} } for (Class<?> iface : declaringClass.getInterfaces()) { try { iface.getMethod(method.getName(), method.getParameterTypes()); return true; } catch (NoSuchMethodException e) {} } return false; }
这种间接判断的逻辑和@Override的语义完全一致——毕竟@Override就是用来确保方法正确重写了父类/接口方法的,所以通过这种方式就能等效判断出方法是否应该被标记@Override。
内容的提问来源于stack exchange,提问作者Ксения Лабутина
相关产品推荐
相关产品推荐

