Java — Thinking about interface rewriting method
I have the following code. The generic ITest interface is extended by the non generic itestdouble interface Itestdouble overrides the op method
When I tried to list all the methods of itestduble, I got two operations How to verify that they are actually the same method?
public class Test { public static void main(String[] args) throws NoSuchMethodException { for (Method m : ITestDouble.class.getmethods()) { System.out.println(m.getDeclaringClass() + ": " + m + "(bridge: " + m.isBridge() + ")"); } } public interface ITestDouble extends ITest<Double> { @Override public int op(Double value); @Override public void other(); } public interface ITest<T extends Number> { public int op(T value); public void other(); } }
Output:
interface Test$ITestDouble: public abstract int Test$ITestDouble.op(java.lang.Double)(bridge: false) interface Test$ITestDouble: public abstract void Test$ITestDouble.other()(bridge: false) interface Test$ITest: public abstract int Test$ITest.op(java.lang.Number)(bridge: false)
PS I know this is with Java class Getmethods () behavior on overridden methods is the same question, but this question has not been answered: isbridge () calls always return false
Editor: I'm also good at any dirty work that can filter out the "copy" operation method for me
Solution
Unfortunately, you can't get this information because itestdouble has a legal method op (number) in terms of JVM, which can be completely independent of op (double) It is actually your java compiler that ensures that methods always coincide
This means that you can create an ill conditioned implementation of itestduble by using a compiler or dynamic proxy before jdk5 and using completely different op (number) and op (double) implementations:
public static void main(String[] args) throws NoSuchMethodException { final Method opNumber = ITest.class.getmethod("op",Number.class); final Method opDouble = ITestDouble.class.getmethod("op",Double.class); final Method other = ITestDouble.class.getmethod("other"); ITestDouble dynamic = (ITestDouble) Proxy.newProxyInstance( ITestDouble.class.getClassLoader(),new Class<?>[]{ITestDouble.class},new InvocationHandler() { @Override public Object invoke(Object proxy,Method m,Object[] args) throws Throwable { if (opDouble.equals(m)) return 1; if (opNumber.equals(m)) return 2; // etc.... return null; } }); System.out.println("op(Double): " + dynamic.op(null); // prints 1. System.out.println("op(Number): " + ((ITest) dynamic).op(null); // prints 2. Compiler gives warning for raw types }
Editor: just learned Java classmate It is a library that can correctly resolve all types of variables in the declaration This is very easy to use:
TypeResolver typeResolver = new TypeResolver(); MemberResolver memberResolver = new MemberResolver(typeResolver); ResolvedType type = typeResolver.resolve(ITestDouble.class); ResolvedTypeWithMembers members = memberResolver.resolve(type,null,null); ResolvedMethod[] methods = members.getMemberMethods();
Now, if you iterate through the method, you will see the following:
void other(); int op(java.lang.Double); int op(java.lang.Double);
You can now easily filter duplicates:
public boolean canOverride(ResolvedMethod m1,ResolvedMethod m2) { if (!m1.getName().equals(m2.getName())) return false; int count = m1.getArgumentCount(); if (count != m2.getArgumentCount()) return false; for (int i = 0; i < count; i++) { if (!m1.getArgumentType(i).equals(m2.getArgumentType(i))) return false; } return true; }