Question

I am programming object serializer/deserializer classes which need to work on c# and java. I handled the issue in the c# part which is below:

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);  

But I encounter a problem in Java generating generic arraylist with the type of the object that is come from xml.

**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);

So, I couldn't find the counterpart of c# code in Java. Thanks for any help!

Ok everybody we handle the problem and I understand my mistake. Thank you very much.

Was it helpful?

Solution

What you're trying to do fundamentally doesn't work in Java. Actually, it's much easier than what you're trying to do (in some ways). Due to type erasure as pointed out by @ElliottFrisch, at runtime, you eliminate the generic type. The generic is only used by compiler to make sure that you don't add an object to a List, for instance, that you're not expecting. At runtime this:

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

becomes

List strings = new ArrayList();

Because the compiler knew about it when it compiled it, you can be assured that, unless you do something crazy with reflection or the like, every object in the list will be a String. No class exists for ArrayList<String>, only ArrayList. The generic collections operate only on Objects and the compiler provides the casting when necessary.

TL;DR: Generics are only in place to help you at compile time. Because you're using reflection to deserialize objects, you won't have that anyway (really, typesafety is a compile time construct as well, you can attempt to call any method on any object, it just won't work unless it's implemented). Your code will be responsible for creating the objects that will be added to the generic container and ensuring that all of the objects are of the expected type.

OTHER TIPS

The Generics in Java is just a compile time trick. Reflection is runtime phenomenon. So there is no need of using generics when you are trying to create a list using reflection. Just create a list with Raw type. It will accept object.

List oList = (List)Class.forName("java.util.ArrayList").newInstance();  

Or maybe something like this?

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>();
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top