我正在编程对象序列化器/反序列化器类,需要处理c#和java。我在下面的c#部分处理了这个问题:
Type listType = typeof(List<>);
Type constructedListType;
type = item.Attributes["Type"].Value;
field = item.Attributes["Field"].Value;
if ((type == "Int32") || (type == "Int64") || (type == "Int16") || (type == "UInt32") || (type == "UInt64") || (type == "UInt16") || (type == "String") || (type == "Datetime") || (type == "Double") || (type == "Single"))
{
constructedListType = listType.MakeGenericType(Type.GetType(String.Format("{0}.{1}", "System", type)));
}
else
{
constructedListType = listType.MakeGenericType(Type.GetType(String.Format("{0}.{1}", WorkingNamespace, type)));
}
IList instance = (IList)Activator.CreateInstance(constructedListType);
但我在Java中遇到了一个问题,即使用来自xml的对象类型生成泛型arraylist。
** Editted
type = attrMap.getNamedItem("Type").getNodeValue();
field = attrMap.getNamedItem("Field").getNodeValue();
type = reverseTypeConvert(type);
Object oList;
if ((type.equals("Integer") || type.equals("Long") || type.equals("Float") || type.equals("Short") || type.equals("String") || type.equals("Double") || type.equals("Date"))) {
oList = Class.forName(String.format("java.util.ArrayList<%s.%s>","java.util",type)).newInstance();
}
else {
oList = Class.forName(String.format("java.util.ArrayList<%s.%s>",this.workingPackage,type)).getGenericSuperclass();
}
if (!field.equals("none")) {
Method setMethod = cObj.getClass().getMethod(String.format("%s%s", "set",field), oList.getClass());
setMethod.invoke(cObj, oList);
}
deSerializeObject(node.getChildNodes(),oList);
所以,我无法在Java中找到c#代码的对应物。 谢谢你的帮助!
好的,我们每个人都能处理这个问题,而且我理解我的错误。 非常感谢你。
答案 0 :(得分:1)
您从根本上尝试做的事情并不适用于Java。实际上,它比你尝试做的更容易(在某些方面)。由于@ElliottFrisch指出type erasure,在运行时,您将删除泛型类型。通用程序仅供编译器使用,以确保您不会将对象添加到List
,例如,您不期望的对象。在运行时:
List<String> strings = new ArrayList<String>();
变为
List strings = new ArrayList();
因为编译器在编译时知道它,所以你可以放心,除非你用反射等做一些疯狂的事情,否则列表中的每个对象都是String
。 ArrayList<String>
不存在任何类,只有ArrayList
。泛型集合仅在Objects
上运行,编译器在必要时提供强制转换。
TL; DR:泛型只是在编译时帮助您。因为您使用反射来反序列化对象,所以无论如何你都不会这样做(实际上,类型安全也是一个编译时构造,你可以尝试来调用任何对象上的任何方法,除非它已经实施,否则它才会胜利。您的代码将负责创建将添加到通用容器中的对象,并确保所有对象都是预期类型。
答案 1 :(得分:0)
Java中的泛型只是一个编译时间技巧。反思是运行时现象。因此,当您尝试使用反射创建列表时,不需要使用泛型。只需创建一个Raw类型的列表。它会接受对象。
List oList = (List)Class.forName("java.util.ArrayList").newInstance();
或者可能是这样的?
List oList;
if ((type.equals("Integer") || type.equals("Long") || type.equals("Float") || type.equals("Short") || type.equals("String") || type.equals("Double") || type.equals("Date"))) {
oList = new ArrayList<Number>();
}
else {
oList = new ArrayList<Object>();
}