Archived

This forum has been archived. Please start a new discussion on GitHub.

Non-paramaterised constructors in *Helper classes generated with Java type metadata

It's nice that you can specify Java metadata for sequence classes to turn them into Lists instead of arrays. However, the default mapping doesn't do quite what I'd want ... consider the following Ice file:
module test {
    ["java:type:java.util.LinkedList"]
    sequence<string> StringList1;

    ["java:type:java.util.LinkedList<java.lang.String>"]
    sequence<string> StringList2;
};

If you run slice2java on that file, you get almost identical Java for the two classes. However, the read() method for StringList1Helper looks like this (note the bolded line):
    public static java.util.List<java.lang.String>
    read(IceInternal.BasicStream __is)
    {
        java.util.List<java.lang.String> __v;
        [b]__v = new java.util.LinkedList();[/b]
        final int __len0 = __is.readAndCheckSeqSize(1);
        for(int __i0 = 0; __i0 < __len0; __i0++)
        {
            String __elem;
            __elem = __is.readString();
            __v.add(__elem);
        }
        return __v;
    }

While for StringList2Helper, it looks like this:
    public static java.util.List<java.lang.String>
    read(IceInternal.BasicStream __is)
    {
        java.util.List<java.lang.String> __v;
        [b]__v = new java.util.LinkedList<java.lang.String>();[/b]
        final int __len0 = __is.readAndCheckSeqSize(1);
        for(int __i0 = 0; __i0 < __len0; __i0++)
        {
            String __elem;
            __elem = __is.readString();
            __v.add(__elem);
        }
        return __v;
    }

So in both cases, slice2java clearly knows it's actually using a java.util.List<java.lang.String>, whether you specify the <T> parameter or not in the metadata (look at the return value). However, for StringList1, it's constructing a raw java.util.LinkedList instead of a java.util.LinkedList<java.lang.String> inside the read() method, which causes Eclipse compiler warnings.

It seems like this is a bug, unless I'm missing something ...

Comments

  • p.s. -- This seems only to be an issue with sequences; dictionaries get the correct <K, V> parameters in the constructor inside read() whether you specify any extra metadata or not.
  • mes
    mes California
    Hi Mary Ellen,

    As described in the manual, the custom type metadata allows you to specify an instance type as well as an optional formal type. Note however that there are certain minimum requirements. For example, here is what the manual says about sequences:
    The compiler requires the formal type to implement java.util.List<E>, where E is the Java mapping of the element type. If you do not specify a formal type, the compiler uses java.util.List<E> by default.

    Since the formal type must implement java.util.List<E>, the instance type must also implement this interface (for obvious reasons). Consequently, I'm not surprised that you get warnings or errors when specifying a non-parameterized custom type such as java.util.LinkedList.

    The Slice compiler doesn't attempt to validate the type supplied in the metadata, as the type could easily be an unknown application-defined subclass of java.util.List<E>.

    If a developer takes advantage of this ability to customize the generated code, they have to accept the fact that errors might not be detected until the generated code is compiled.

    Regards,
    Mark
  • Ah, okay -- I guess I do need to keep giving the full formal type then. Thought I could get away with a bit less code there. (I collaborate with C++ developers who were a bit suspicious when they saw all that Java metadata in the Slice files. :) )

    Any plans on changing the default Java mapping for all sequences to List<T> instead of arrays? Maybe providing a global metadata parameter like "java:sequence:java.util.LinkedList<T>" or something so people can use their favourite List subclass, instead of having to specify it for all sequences across a project.