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;
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>