- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试解码名为 Key 的泛型类的 ArrayList。
Key 有 setValue() 方法,该方法接收通用参数。
@XMLRootElement(name = "Key")
public class Key<T>{
@XMLElement(name = "Key")
public setKey(T value){
this.value = value
}
}
@XMLElementWrapper(name = "Keys")
@XMLElement(name = "Key")
public setKeys(ArrayList<Key> keys){
this.keys = keys;
}
<Keys>
<Key>2</Key>
</Keys>
运行代码将创建 ArrayList 并且其中将有一个 Key 对象。但 key 将为空。
(我尝试过调试,发现它没有调用该类的 setKey() setter)
与它的通用性有什么关系吗?提前致谢。
在过去的一天里,我对此进行了很多调试,现在我可以说,问题在于实例化 ArrayList 后,在 XML 中为每个键标签创建每个键时,解码器使用键的空构造函数,并且从不调用它的 setter ,因此我有一个包含键的 ArrayList,其“值”数据成员为 null
。
谁能解释一下我做错了什么吗?为什么 setter 没有被调用?
谢谢。
最佳答案
你可能不走运。解码器如何知道 2 是一个整数,而不是一个 double 或 long 或时间戳或其他具有可以将 2 解析为自身的自定义适配器的类。
您想要的注释基本上如下(减去我将在稍后解释的 @XmlJavaTypeAdapter),但如果您尝试在没有适配器的情况下运行该代码,您将得到 NullPointerException,因为 JAXB 无法处理对象上的 @XmlValue 注释(这就是它处理 T 的方式)。 JAXB 无法处理它的原因是它无法知道该对象是什么。
现在,如果您有自己的自定义规则来确定 T 的类型(例如,当来自 XML 时,T 始终为整数,或者如果不包含“.”,则 T 为整数,否则为 Double),那么您可以使用适配器实现您自己的逻辑,这就是我在下面演示的内容(我使用了第二条规则)。
@XmlRootElement(name="root")
public class SO {
private List<Key<?>> keys;
@XmlElementWrapper(name="Keys")
@XmlElement(name="Key")
public void setKeys(List<Key<?>> keys) {
this.keys = keys;
}
public List<Key<?>> getKeys() {
return keys;
}
@XmlType
public static class Key<T> {
private T val;
@XmlValue
@XmlJavaTypeAdapter(ToStringAdapter.class)
public void setKey(T val) {
this.val = val;
}
public String toString() {
return "Key(" + val + ")";
}
}
public static class ToStringAdapter extends XmlAdapter<String, Object> {
@Override
public Object unmarshal(String v) throws Exception {
if(v.contains(".")) {
return Double.parseDouble(v);
} else {
return Integer.parseInt(v);
}
}
@Override
public String marshal(Object v) throws Exception {
return v.toString(); //Will never be called anyway so you could also throw an exception here
}
}
private static final String XML_INT = "<root><Keys><Key>2</Key></Keys></root>";
private static final String XML_DOUBLE = "<root><Keys><Key>2.7</Key></Keys></root>";
public static void main(String [] args) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(Key.class, SO.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
SO so = (SO) unmarshaller.unmarshal(new StringReader(XML_INT));
System.out.print(so.keys);
System.out.println(" " + so.keys.get(0).val.getClass().getSimpleName());
so = (SO) unmarshaller.unmarshal(new StringReader(XML_DOUBLE));
System.out.print(so.keys);
System.out.println(" " + so.keys.get(0).val.getClass().getSimpleName());
}
}
关于java - JAXB 包装的通用对象的 Setter 方法从未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34532456/
背景 我最近在 merge 期间遇到了一个意外未 merge 的文档文件的问题。 无论出于何种原因,我搞砸了 merge 并有效地删除了文件(和其他几个文件),因为我忘记了它们的存在。 现在我想查看我
我在我的网站上使用旧的 mysql 版本和 php 版本 4。 我的表结构: | orders_status_history_id | orders_id | orders_status_id |
我是一名优秀的程序员,十分优秀!