Получение информации о типе класса для элементов в коллекции - PullRequest
0 голосов
/ 29 мая 2010

Я хотел бы получить доступ к типу Объекта в Коллекции Ниже приведен упрощенный пример того, когда и почему я могу это сделать Это вообще возможно?

List<Address> addressList = new LinkedList<Address>();

Main.addElement(addressList);

Class Main{
   public void addElement(Object inArgument){
      List<Object> argument = (List<Object>)inArgument;
      argument.add( /* WOULD LIKE TO CREATE A NEW OBJECT OF THE APPROPRIATE TYPE
                       HERE, IN THIS CASE, IT WOULD BE OF TYPE: "Address" */ );
   }
}

Ответы [ 4 ]

5 голосов
/ 29 мая 2010

Нет, вы не можете сделать это с текущей реализацией обобщений Java. Параметры типа «стираются» во время компиляции.

С помощью отражения можно определить информацию о параметрах типа для параметров метода и возвращаемых типов, а также для переменных-членов, но в этом случае это не поможет.

В качестве практического обходного пути большинство API, которые хотят сделать что-то подобное, принимают экземпляр Class в качестве второго параметра. Например:

public void addElement(Collection<T> c, Class<? extends T> clz) 
  throws Exception
{
  Constructor<? extends T> ctor = clz.getConstructor();
  T el = ctor.newInstance();
  c.add(el);
}
3 голосов
/ 29 мая 2010

Это невозможно сделать так, как определен ваш текущий метод, так как общие сведения недоступны во время выполнения. Альтернатива - сделать это:

public <T> void addElement(List<T> inArgument, Class<? extends T> clazz){
   T t = clazz.newInstnace();
   inArgument.add(t);
   // exception handling omitted for brevity
}

Затем вы звоните addElement, как это

addElement(addressList, Address.class);

См. JLS для деталей об общих типах и стирании типов. В двух словах, стирание типа отвечает за такое поведение:

Vector<String> x = new Vector<String>(); 
Vector<Integer> y = new Vector<Integer>(); 
boolean b = x.getClass() == y.getClass();

Результат: b==true.

См.

0 голосов
/ 29 мая 2010

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

List<Address> addressList = new LinkedList<Address>();
List<Object> stuffToSeeInWashington = new LinkedList<Object>();

Main.addWhiteHouse(addressList);
Main.addWhiteHouse(stuffToSeeInWashington);

Class Main{
   public void addWhiteHouse(List<? super Address> argument){
      Address whiteHouse = new Address("1600 Pennsylvania Ave");
      argument.add( whiteHouse ) ;
   }
}
0 голосов
/ 29 мая 2010
argument.add( null );

null - это значение каждого типа ссылки: P

А если серьезно, я не знаю, почему вы хотели бы сделать это. Это подразумевает, что для вашего типа есть какое-то значение «по умолчанию», что не относится к типам в целом.

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