Подтвердить что ты не робот

Преобразование не общего типа List в тип Generic List в Java 1.5

У меня есть список, который, как гарантируется, содержит только один объект типа. Это создается некоторым базовым кодом в библиотеке, которую я не могу обновить. Я хочу создать List <ObjectType> на основе входящего объекта List, чтобы мой код вызова говорил с List <ObjectType> .

Какой лучший способ преобразовать Список (или любую другую коллекцию объектов) в List <ObjectType> .

4b9b3361

Ответ 1

При взаимодействии с устаревшим кодом, который не задает параметры типа для общих типов, используйте шаблон. Например, предположим, что вы вызываете метод в старой библиотеке, которая просто возвращает raw Collection:

Collection getItems();

В вашем коде присвойте результат переменной, объявленной с помощью подстановочного знака:

Collection<?> items = widget.getItems();

Таким образом, вы сохраняете безопасность типов, чтобы вы не получали никаких предупреждений.

Устаревший код может указывать (в комментарии, скорее всего), какие должны быть общие параметры. Например:

/**
 * @return the items, as a Collection of {@link Item} instances.
 */
Collection getItems();

В этом случае у вас есть выбор. Вы можете привести результат к Collection<Item>, но если вы это сделаете, вы полагаетесь на 100% на стороннюю библиотеку и отбрасываете уверенность в генерируемых типах Java: что любой ClassCastException, созданный во время выполнения, будет происходить прямо на явное литье.

Что делать, если вы не полностью доверяете сторонней библиотеке, но все равно нужно создать Collection<Item>? Затем создайте новую коллекцию и добавьте содержимое после их добавления к ожидаемому типу. Таким образом, если в библиотеке есть ошибка, вы сразу же узнаете об этом, вместо того, чтобы иметь некоторый код далеко и намного позже таинственно взорвали с помощью ClassCastException.

Например:

Collection<?> tmp = widget.getItems();
Collection<Item> items = new ArrayList<Item>(tmp.size());
for (Object o : tmp)
  items.add((Item) o); /* Any type error will be discovered here! */

В случае, когда параметр типа не известен во время компиляции, вы можете использовать фабрики коллекции, проверенные типом, в Collections.

Ответ 2

Вы можете просто перечислить список:

  List raw = new ArrayList();
  List<String> generic = (List<String>) raw;

Ответ 3

Самый лучший и безопасный способ - использовать метод java.util.Collections 'checkedList (Список списка, Тип класса)'

С помощью этого метода все элементы в вашем старом списке будут проверены как можно раньше.

Ответ 4

Попробуйте следующее:

List<ObjectType> objectsWithType = Arrays.asList((ObjectType[])wildcardObjects).toArray());

Но помните, что это создаст список фиксированной длины. Если вы попытаетесь добавить или удалить элемент из этого списка, он выдает ошибку. Поэтому всегда будьте осторожны при использовании Arrays.asList().

Ответ 5

Если вы просто нажмете на List<T> в любом старом месте, вы получите предупреждение о "непроверенном" компиляторе. Мы решили это, переместив его к утилитарному методу.

public class Lists {
    @SuppressWarnings({"unchecked"})
    public static <T> List<T> cast(List<?> list) {
        return (List<T>) list;
    }
}

Теперь вызывающий абонент не получает предупреждения, например:

for (Element child : Lists.<Element>cast(parent.getChildren())) {
    // ...
}

Эта утилита checkedList в теории представляет собой отличную идею, но на практике это отстойно проходить в классе, который вы ожидаете. Я надеюсь, что Java в конечном итоге получит информацию о типичной типизации во время выполнения.