Добавление Java в общий список неизвестного типа - PullRequest
13 голосов
/ 29 июня 2011

Я сталкивался с чем-то, с чем я не сталкивался ранее в Java, то есть мне нужно создать новый экземпляр, скажем, класса ArrayList во время выполнения без назначения известного типа, а затем добавить данные в список. Это звучит немного расплывчато, так что вот пример:

Class<?> c = i.getClass();

Constructor<?> con = ArrayList.class.getConstructor();
ArrayList<?> al = (ArrayList<?>)con.newInstance();

al.add("something");

Теперь причина, по которой я делаю это, а не просто использование обобщений, заключается в том, что обобщенные элементы уже интенсивно используются, и переменная «i» в этом примере будет дана для использования в качестве типа «?». Я бы на самом деле не стал добавлять другой универсальный шаблон, так как это потребовало бы больше работы для пользователя и было бы гораздо менее гибким в конечном дизайне. Есть ли способ использовать что-то вроде ниже (Примечание: то, что ниже, не работает). У кого-нибудь есть идеи?

ArrayList<c> al = (ArrayList<c>)con.newInstance();

Ответы [ 3 ]

11 голосов
/ 29 июня 2011

Вы не можете добавлять объекты в коллекцию, определенную с использованием универсальных шаблонов. Эта тема может вам помочь.

Действительно, вы создаете коллекцию, которая, да, является супертипом каждой коллекции, и, как таковая, может быть назначена любой коллекции универсальных шаблонов; но это слишком универсально, чтобы разрешить любую операцию добавления, так как компилятор не может проверить тип того, что вы добавляете. И это именно то, для чего предназначены дженерики: проверка типов.

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

Ваша коллекция слишком универсальна, чтобы в нее можно было добавлять что-либо. Проблема не имеет ничего общего с правой стороной присвоения (с помощью одиночного или отраженного), она в типе объявления левой стороны с использованием подстановочных знаков.

8 голосов
/ 29 июня 2011

Если я понимаю, что вы имеете в виду, у вас есть класс C, который неизвестен во время компиляции, и вы хотите создать ArrayList<C> безопасным для типов способом. Это возможно:

Class<?> c = ...;
ArrayList<?> al = listOf(c);

static <T> ArrayList<T> listOf(Class<T> clazz)
{
    return new ArrayList<T>();
}

Это теоретически правильный способ сделать это. Но кого это волнует. Мы все знаем об удалении типов, и нет никаких шансов, что Java откажется от стирания типов и добавит тип времени выполнения для параметров типа. Таким образом, вы можете просто использовать необработанные типы и свободно разыгрывать при условии, что вы знаете, что делаете.

5 голосов
/ 29 июня 2011

Вы можете просто использовать ArrayList<Object>, к которому вы можете add() что угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...