使用通过反射创建的对象的问题

时间:2014-08-11 13:41:31

标签: java generics reflection

我正在尝试编写一个可用于向一组订阅者发送消息的程序。用于传递消息的订户和技术并不重要。消息类型由XML模式定义,并实现为Java API。所有消息类型都有一个抽象的超类型。 API定义了允许在XML和Java之间进行转换的静态方法,反之亦然(fromXML()toXML())。

我在实施这个方面遇到了困难。我已经在下面列出了我想要开始工作的代码示例。它不像编写的那样编译。抽象超类型是MessageType类,我的计划是传递"真实"的名称。消息类型,并使此代码创建必要的对象,以执行发送指定子类型的消息所需的内容。

public class Writer {

  public static void runExample(String[] args) throws Exception {
    UUID serviceID = UUID.fromString(args[1]);

    ServiceBus bus = ServiceBus.getServiceBus();
    bus.init(serviceID);

    // The intention is to pass the message type name so that this code can be used for any
    // "message" type.
    String msgName = args[0];

    // Get the message type class from the passed name.
    Class<? extends MessageType> msgClass = (Class<? extends MessageType>) Class.forName(msgName);

    // Create a writer for the specified message type.
    MessageWriter<? extends MessageType> writer = bus.createWriter(msgName, msgClass);

    // Read in some XML content from a file.
    String xml = loadMsg(args[2]);

    // Want to do something like this:
    msgClass object = msgClass.fromXML(xml);
    // Of course, this does not compile. Is there a way to do this?

    // Create a java object of the message type from the XML read in.
    MessageType object = MessageType.fromXML(xml);

    // With the line above the statement below fails to compile with the error:
    //   The method write(capture#4-of ? extends MessageType) in the type
    //   MessageWriter<capture#4-of ? extends MessageType> is not applicable for
    //   the arguments (MessageType)

    writer.write(object);
  }

  private static String loadMsg(String fileName) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
    String line = null;
    StringBuilder sb = new StringBuilder();

    do {
    line = reader.readLine();
    if (line != null)
      sb.append(line);
    } while (line != null);

    reader.close();
    return sb.toString();
  }

}

是否有人知道我是否有可能做我上面所述的事情?

1 个答案:

答案 0 :(得分:1)

由于您的WriterMessageWriter<? extends MessageType>,这意味着它可以是任何MessageWriter,其中MessageType的子类。所以实际的实例可能是MessageWriter<MySuperMessageType>。由于编译器无法将MessageType实例确认为MySuperMessageType,因此编译器会将其失败。

如果作者属于MessageWriter<MessageType>MessageWritier<? super MessageType>类型,则可行。另一种选择是创建一个通用方法......

private <T extends MessageType> myMethod(Class<T> type){
   MessageWriter<T> writer = bus.createWriter(msgName, msgClass);
   String xml = loadMsg(args[2]);
   // you could use reflection to get the public static methods from the class instance
   // msgClass object = msgClass.fromXML(xml);
   T object = (T) MessageType.fromXML(xml);
   writer.write(object);
}