在运行时模仿给定接口的实现方法

时间:2018-05-05 21:46:13

标签: java generics reflection interface

假设我有一个未知的接口,我希望能够构造一个对象,当用户从接口上调用某个方法时,返回该接口指定的内容。 例如。拥有一个Class class对象,代表未知的Interface,我希望能够构造一个Object,其行为类似于正确实现Interface的东西。 例如,假设我正在研究方法

public <E> E myMethod(Class<E> class){
    ...
    return res;
}

其中class表示未知接口,例如

public <E> interface Writer{
    public String write(String s);
}
Class<E> class = Writer.class;

我现在想要的就是像

这样的任何电话
returnedFromMyMethod.write(s);

实际完成这项工作,例如返回给定字符串 我知道有使用的反射,因为所有这些都在运行时进行,我们不知道界面到底是什么。但无法弄清楚。有什么想法吗?

编辑:避免误会。

  1. 这一切都在运行中。我不知道那个界面是什么。 它可以是Writer,可能是RunnableComparable或任何 其他。 肯定一个界面。
  2. 我们的目标没有 存在,它没有我们想要的任何方法。这就像构建 从零开始的新对象(参数化类型)。
  3. 所以问题是创建一个模仿从给定接口实现所有方法的对象

3 个答案:

答案 0 :(得分:0)

将您的方法和界面更改为

public <E extends Writer> E myMethod(Class<E> clazz) {      
    ...
    return res;
}

public interface Writer {
    public String write(String s);
}

现在,您可以在write(String s)的返回值上调用myMethod(Class<E> clazz)方法。

Writer w = myMethod(WriterImpl.class);
w.write("any string");

答案 1 :(得分:0)

您可以将该类放入java反编译器(如javadecompilers.com)中,然后您可以找到它扩展的界面,或者您可以像这样进入反射路径:

//Assuming the class only extends 1 interface you can do this
Class<?>[] interfaces = class.getClass().getInterfaces();
//Now since we know interfaces[0] is the desired interface, we can get its name
System.out.printLn(intefaces[0].getName()); //You don't have to print the name if you're just going to continue with reflection
//now we're going to define the s variable which will hold what the method returns
String result = "";
//Next using reflection we're going to get the desired method, invoke it, give reflection it's return type and your argument
try {
    result = interfaces([0].getMethod("write").invoke(String.class, args);
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
            | SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

如果您希望使用反射,这就是您可以做的。 相反,如果我错过了解问题是什么,任何实现接口的类都会自动调用这些方法。因此,做class.write(s);会像正常一样返回一个字符串。

答案 2 :(得分:0)

您可以创建dynamic proxy

@SuppressWarnings("unchecked")
public static <E> E myMethod(Class<E> cls) {
    return (E) Proxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls },
        (Object proxy, Method method, Object[] arguments) -> {
            // handle the invocation of the given method
            return null; // return something actual
        });
}

Writer result = makeProxy(Writer.class); // e.g.

只要你有一个如何处理调用的计划。当然,没有办法自动地做到这一点。