Java通过反射创建通用Arraylist

时间:2014-05-02 13:46:03

标签: c# java generics reflection arraylist

我正在编程对象序列化器/反序列化器类,需要处理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#代码的对应物。 谢谢你的帮助!

好的,我们每个人都能处理这个问题,而且我理解我的错误。 非常感谢你。

2 个答案:

答案 0 :(得分:1)

您从根本上尝试做的事情并不适用于Java。实际上,它比你尝试做的更容易(在某些方面)。由于@ElliottFrisch指出type erasure,在运行时,您将删除泛型类型。通用程序仅供编译器使用,以确保您不会将对象添加到List,例如,您不期望的对象。在运行时:

List<String> strings = new ArrayList<String>();

变为

List strings = new ArrayList();

因为编译器在编译时知道它,所以你可以放心,除非你用反射等做一些疯狂的事情,否则列表中的每个对象都是StringArrayList<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>();
        }