Thilo
Thilo

Reputation: 262494

Warning: A generic array of Object&Serializable&Comparable<?> is created for a varargs parameter

If I call a (generic) varargs method with objects of different classes, I get an interesting warning:

List<?> result =  Arrays.asList("1", 1);

A generic array of Object&Serializable&Comparable is created for a varargs parameter

I can get rid of the warning by casting to a common interface or class,

List<Serializable> result = asList((Serializable) "1", (Serializable) 1);

but what does Object&Serializable&Comparable<?> mean? Can it be used in generic type annotations on method signatures as well (like extends or super)?

Upvotes: 2

Views: 1647

Answers (3)

Aaron Digulla
Aaron Digulla

Reputation: 328556

If you have a generic type like Foo<...>, then you can use a helper method to call Arrays.asList() for you:

public static List<Foo<?>> asList( Foo<?> ... foos ) {
    return Arrays.asList( foos );
}

The Java compiler will create a generic array for the varargs parameter which you can then safely use in the call to Arrays.asList(). If you want all Foo to have the same inner type:

public static <T> List<Foo<T>> asList( Foo<T> ... foos ) {
    return Arrays.asList( foos );
}

Upvotes: 0

missingfaktor
missingfaktor

Reputation: 92026

The class Object and the interfaces Comparable and Serializable are the supertypes that the classes Integer and String have in common.

Due to type erasure in generics and covariance of arrays, Generics and arrays don't mix very well with each other. The method Arrays#asList takes a varargs as input, and in Java, varargs are internally implemented with arrays. Hence the warning. (You can read more about this in Josh Bloch's Effective Java.)

Now coming to your second question, <Object & Comparable<Whatever> & Serializable> can be used in method signatures to specify the constraints on type parameters. (See this answer.) Java however does not allow such types in generic type annotations.

In other words, the following is valid:

public static void <A extends Comparable<A> & Serializable> meth(A a);

but the following is not:

List<Serializable & SomeOtherInterface> list = ...;

Upvotes: 3

Petro Semeniuk
Petro Semeniuk

Reputation: 7038

I think because all objects types are Serializable and Comparable (String and Integer) then compiler saying that all elements in array will have Object type AND implements Serializable and Comparable interfaces.

I doubt that Serializable&Comparable could be used normally in java code, you always can implement them normally and receive the same warning :-)

public class ComparableAndSerializableClass implements Comparable<ComparableAndSerializableClass>, Serializable{

    public static void main(String[] args) {
        List<?> result = Arrays.asList( "1", 1, new ComparableAndSerializableClass());
        for (Object comp : result) {
            System.out.println(comp.getClass());
        }
    }

    @Override
    public int compareTo(ComparableAndSerializableClass o) {
        return 0;
    }
}

Upvotes: 1

Related Questions