Предупреждение: для параметра varargs создается общий массив Object & Serializable & Comparable <?> - PullRequest
2 голосов
/ 26 ноября 2010

Если я вызываю (универсальный) метод varargs с объектами разных классов, я получаю интересное предупреждение:

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

Для параметра varargs создается общий массив Object & Serializable & Comparable

Я могу избавиться от предупреждения, приведя к общему интерфейсу или классу,

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

но что означает Object&Serializable&Comparable<?>? Может ли оно использоваться в аннотациях универсального типа в сигнатурах методов (например, extends или super)?

Ответы [ 3 ]

3 голосов
/ 26 ноября 2010

Класс Object и интерфейсы Comparable и Serializable являются супертипами, общими для классов Integer и String.

Из-за стирания типов в дженериках и ковариации массивов, дженерики и массивы не очень хорошо сочетаются друг с другом. Метод Arrays#asList принимает в качестве входных данных переменные, а в Java переменные внутренне реализуются с помощью массивов. Отсюда и предупреждение. (Вы можете прочитать больше об этом в «Эффективной Java» Джоша Блоха.)

Теперь перейдем ко второму вопросу: <Object & Comparable<Whatever> & Serializable> можно использовать в сигнатурах методов для указания ограничений на параметры типа. (См. этот ответ .) Java, однако, не допускает такие типы в аннотациях универсальных типов.

Другими словами, действует следующее:

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

но это не так:

List<Serializable & SomeOtherInterface> list = ...;
1 голос
/ 26 ноября 2010

Я думаю, потому что все типы объектов являются Serializable и Comparable (String и Integer), тогда компилятор говорит, что все элементы в массиве будут иметь тип Object AND и реализует интерфейсы Serializable и Comparable.

Я сомневаюсь, что можно использовать Serializable & ComparableОбычно в Java-коде вы всегда можете их реализовать и получать одно и то же предупреждение: -)

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;
    }
}
0 голосов
/ 19 марта 2015

Если у вас есть универсальный тип, такой как Foo<...>, вы можете использовать вспомогательный метод для вызова Arrays.asList() для вас:

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

Компилятор Java создаст универсальный массив для параметра varargsкоторый вы затем можете безопасно использовать при звонке на Arrays.asList().Если вы хотите, чтобы все Foo имели одинаковый внутренний тип:

public static <T> List<Foo<T>> asList( Foo<T> ... foos ) {
    return Arrays.asList( foos );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...