Java 如何整理和取消整理对象类型字段?
我有一个带有泛型方法的接口Java 如何整理和取消整理对象类型字段?,java,marshalling,xstream,unmarshalling,Java,Marshalling,Xstream,Unmarshalling,我有一个带有泛型方法的接口 public interface A { public void setValue(Object value); public Object getValue(); } 实现此接口但将值限制为某些特定枚举类的类(例如值为X、Y、Z): 对于编组和解编组,我编写了一个特定的转换器 为了我的编组 public boolean canConvert(Class clazz) { return A.class.isAssignableFrom(clazz
public interface A {
public void setValue(Object value);
public Object getValue();
}
实现此接口但将值限制为某些特定枚举类的类(例如值为X、Y、Z):
对于编组和解编组,我编写了一个特定的转换器
为了我的编组
public boolean canConvert(Class clazz) {
return A.class.isAssignableFrom(clazz);
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
...
A entry = (A) source;
writer.startNode("value");
context.convertAnother(entry.getValue());
writer.endNode();
...
}
这将生成一个类B的实例
...
<value>X</value>
...
我放置了Object.class
,因为我不知道它包含哪种对象类型。我希望XStream能够添加一些关于这方面的信息
这会失败,因为Object type=context.convertOther(extra,Object.class)
与“X”字符串一起工作,而不一定要生成MyEnum类型的对象,这是extra.setValue(type)
所期望的
如何强制或添加信息,以便XStream知道它必须生成的对象类型?
感谢阅读这篇长篇文章…默认情况下,如果XStream遇到一个对象,其类派生自XStream可以转换的类,它会将类名放入“class”属性中 如果您的转换器
canConvert()
为Object.class
返回true
,那么您实际上是在覆盖XStream的默认转换器,您有责任执行以前的操作。除非实现一种自己存储类型信息的方法,否则在XML中就不会有关于类的信息
要么放弃
A.class
/对象.class
转换器(因为没有显示转换器,所以不确定您拥有什么),使转换器仅特定于具体类(canConvert
仅对B.class
返回true),或者至少通过为基本接口而不是一般的对象制作转换器来限制损坏。类转换器(canConvert
为a.class.isAssignableFrom(类)
)返回true)在这种情况下,由您决定如何在文件中存储有关具体类的类的信息。我按照此处的建议,添加了一些有关值的类的信息,并使用此信息进行解组。我将发布我的工作解决方案,以供可能发现此问题的任何其他读者参考:
public static class ExtraSearchOptionConverter implements Converter {
public boolean canConvert(Class type) {
return ExtraSearchOption.class.isAssignableFrom(type);
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
ExtraSearchOption entry = (ExtraSearchOption) source;
...
if (entry.getValue() != null) {
writer.startNode("value");
writer.addAttribute("class", entry.getValue().getClass().getName());
context.convertAnother(entry.getValue());
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
ExtraSearchOption extra = new ExtraSearchOption();
...
if (reader.hasMoreChildren()) {
reader.moveDown();
String className = reader.getAttribute("class");
Class<?> valueClass = null;
if (className != null) {
try {
valueClass = Class.forName(className);
Object type = context.convertAnother(extra, valueClass);
extra.setValue(type);
} catch (ClassNotFoundException ex) {
logger.error("While retrieving class for ExtraSearchOptions value", ex);
}
}
reader.moveUp();
}
return extra;
}
}
公共静态类ExtraSearchOptionConverter实现转换器{
公共布尔canConvert(类类型){
返回ExtraSearchOption.class.isAssignableFrom(类型);
}
公共无效封送处理(对象源、HierarchycalStreamWriter编写器、封送上下文){
ExtraSearchOption条目=(ExtraSearchOption)源;
...
if(entry.getValue()!=null){
作者:startNode(“价值”);
writer.addAttribute(“类”,entry.getValue().getClass().getName());
convertOther(entry.getValue());
writer.endNode();
}
}
公共对象解组(HierarchycalStreamReader读取器,解组上下文){
ExtraSearchOption extra=新的ExtraSearchOption();
...
if(reader.hasMoreChildren()){
reader.moveDown();
字符串className=reader.getAttribute(“类”);
Class valueClass=null;
if(className!=null){
试一试{
valueClass=Class.forName(className);
对象类型=context.convertOther(额外,valueClass);
额外设置值(类型);
}捕获(ClassNotFoundException ex){
logger.error(“为ExtraSearchOptions值检索类时”,ex);
}
}
reader.moveUp();
}
额外返还;
}
}
请显示自定义转换器的canConvert()
实现。这看起来应该是正常的。顺便说一下,欢迎来到Stack Overflow!一般来说,这里的做法是将答案仅限于回答问题,并直接对问题本身或相关答案发表评论。因为这篇文章确实包含了一个相关的答案,我将对其进行编辑,将其重新表述为一个答案(否则我建议删除它)。谢谢!:)(我假设您的解决方案是有效的;请确认这种情况,以便我知道编辑是好的。)Mod:请忽略预编辑标志。
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
...
reader.moveDown();
Object type = context.convertAnother(extra, Object.class);
extra.setValue(type);
reader.moveUp();
...
return extra;
}
public static class ExtraSearchOptionConverter implements Converter {
public boolean canConvert(Class type) {
return ExtraSearchOption.class.isAssignableFrom(type);
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
ExtraSearchOption entry = (ExtraSearchOption) source;
...
if (entry.getValue() != null) {
writer.startNode("value");
writer.addAttribute("class", entry.getValue().getClass().getName());
context.convertAnother(entry.getValue());
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
ExtraSearchOption extra = new ExtraSearchOption();
...
if (reader.hasMoreChildren()) {
reader.moveDown();
String className = reader.getAttribute("class");
Class<?> valueClass = null;
if (className != null) {
try {
valueClass = Class.forName(className);
Object type = context.convertAnother(extra, valueClass);
extra.setValue(type);
} catch (ClassNotFoundException ex) {
logger.error("While retrieving class for ExtraSearchOptions value", ex);
}
}
reader.moveUp();
}
return extra;
}
}