我正在尝试编写一个程序,可用于向一组订阅者发送消息。用于传递消息的订阅者和技术并不重要。消息类型由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();
}
}
有谁知道我上面描述的是否有可能做到?
由于您的Writer
是MessageWriter<? 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);
}