不采用反射时,调用大概是这样子:
IRecvResponse recver = new RecvResponseImp();
Stub.instanceService(recver);
其中,IRecvResponse接口类和Stub类是别人提供的,我要产生一个实现IRecvResponse接口类的对象,然后将这个对象注册到Stub中,当Stub中有消息到来的时候,Stub会回调我注册进去的对象,这样我就能在RecvResponseImp中处理消息了。如果是采用反射调用,虽然我能将IRecvResponse接口反射出来,但是不知道怎么用它产生RecvResponseImp对象,也就是说,没法用反射方式调用instanceService函数,因为我构造不出recver参数来。请问,这种回调方式是不是用不了反射机制啊?

解决方案 »

  1.   

    好像没有楼主想象的那么复杂吧。就是用反射创建一个RecvResponseImp对象。并且RecvResponseImp构造方法还是没有参数的。try {
    IRecvResponse recver = (IRecvResponse) Class.forName("cn.com.RecvResponseImp").newInstance();//填写RecvResponseImp类正确的包名
    } catch (Exception e) {
    e.printStackTrace();
    }
      

  2.   

    反射跟常规调用的主要差异,是反射可以不需要定义接口。只需要直接约定一个函数即可,比如:
    public void instanceService(Object callbackHandler, String methodName) {调用时则:
    Method m = callbackHandler.getClass().getDeclaredMethod(methodName); 
    m.invoke(callbackHandler);另一种方式则是直接传递回调的类名和函数名,但比较少用,因为这样做的话,回调主体不明确:
    public void instanceService(String callbackClass, String methodName) {
      

  3.   

    接口类怎么创建实例?必须是接口的实现类才能创建实例
    如1L所说的,通过反射生成接口的实现类RecvResponseImp的实例(前提是别人也把实现类RecvResponseImp提供给你)
      

  4.   

    谢谢大家的回复,可能是我说得不明白。instanceService方法是别人已经写好放在jar包中的,我是改不了的。这个方法有一个参数,类型是IRecvResponse,IRecvResponse也是放在别人的jar包中的。别人的想法是让我产生一个类(暂且叫做RecvResponseImp)实例,通过instanceService方法注册给他,当他收到业务消息时,他通过我注册给它的引用进行调用。也就是说,他负责将收到的消息通过这种方式告诉我,而我负责具体怎么处理。
    public class RecvResponseImp implements IRecvResponse {

    /**
     * 响应消息
     *  String : JSON格式的消息
     *  byte[] : 二进制消息内容 (可能有可能无,和具体消息有关)
     */
    public void responseAction(String message, byte[] accessory) {
                  // 我对业务消息进行具体处理         }
    }
    采用反射方式时,因为编译时我并没有IRecvResponse,故我无法产生RecvResponseImp类,进而没法通过反射调用instanceService方法。
      

  5.   

    to 2L:
    别人已经把instanceService方法写好了,他没有按你说的那样写,而是提供了一个IRecvResponse接口让我实现,然后他通过IRecvResponse接口进行回调。
      

  6.   

    to 2L:你这种回调方式挺帅的:
    Method m = callbackHandler.getClass().getDeclaredMethod(methodName);  
    m.invoke(callbackHandler);
    相当于约定了一个方法名,而他提供IRecvResponse的方式相当于约定了一个接口类。
    2L的方式更加灵活,更像C语言回调的方式,即注册一个函数指针。
      

  7.   

    没有IRecvResponse、RecvResponseImp所在的包,那向对方把这个包要过来。
    如果不方便给,那有IRecvResponse 的接口说明也可以,在你本地写一个接口,一个实现类。
    接口说明也没有,那就要对方提供一个通用接口。
      

  8.   

    既然楼主说已经把IRecvResponse接口提供给你了,那就可以了,还有什么问题呢。
      

  9.   

    to 8楼:
    包当然有了,只是我不想使用直接调用的方式。我自己定义一个IRecvResponse接口,虽然和别人的一摸一样,但是调用instanceService时,抛出异常,说参数不合法。
    为什么我想用反射呢,是因为我不想把别人的若干个jar包加入我的eclipse插件工程中。
      

  10.   

    try {
                IRecvResponse recver = (IRecvResponse) Class.forName("cn.com.RecvResponseImp").newInstance();//填写RecvResponseImp类正确的包名
            } catch (Exception e) {
                e.printStackTrace();
            }这样就OK了
      

  11.   

    可能大家还是没明白我的意思,RecvResponseImp是我的实现类,不用反射的。
      

  12.   

    感觉楼主有点违背人家提供接口的本意了...真的在特殊状况下,你只要自定义与IRecvResponse一样的接口也应该没问题的,有异常是否说明你没定义好呢?
      

  13.   


    如果是这样,可以采用动态编译,即以参考 com.sun.tools.javac包不过既然人家都把jar提供给你了,为什么不直接导入使用,非要复杂化