Java, добавляющий общий список неизвестного типа
Я пришел к чему-то, чего раньше не встречал в 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();
Ответы
Ответ 1
Вы не можете добавлять объекты в коллекции, определенные с помощью подстановочных знаков. Этот поток может вам помочь.
Действительно, вы создаете коллекцию, которая, да, супер тип каждой коллекции и, как таковая, может быть назначена любой коллекции дженериков; но он слишком общий, чтобы разрешить любую операцию добавления, поскольку компилятор не может проверить тип того, что вы добавляете. И именно то, что предназначены для дженериков: тип проверки.
Я предлагаю вам прочитать поток и посмотреть, что он также относится к тому, что вы хотите сделать.
Ваша коллекция просто слишком универсальна, чтобы можно было добавить что-либо. Проблема не имеет ничего общего с правой стороной назначения (с использованием одноэлементного или отраженного), это в типе декларации левой стороны с использованием подстановочных знаков.
Ответ 2
Если я получу то, что вы имеете в виду, у вас есть класс C, который неизвестен во время компиляции, и вы хотите создать ArrayList<C>
безопасным типом. Это возможно:
Class<?> c = ...;
ArrayList<?> al = listOf(c);
static <T> ArrayList<T> listOf(Class<T> clazz)
{
return new ArrayList<T>();
}
Это теоретически правильный способ сделать это. Но кого это волнует. Мы все знаем о стирании стилей, и нет никакой возможности, чтобы Java сбросила стирание типа и добавила тип времени выполнения для параметров типа. Таким образом, вы можете просто использовать необработанные типы и использовать их свободно, если знаете, что делаете.
Ответ 3
Вы можете просто использовать ArrayList<Object>
, к которому вы можете add()
что угодно.