2015-06-21 2 views
1

Попытка полностью понять Generics в Java, я столкнулся с проблемой, с которой я действительно не мог обойтись, и не нашел конкретного решения в Интернете. У меня есть этот метод:Массивы, список и обобщения в Java

public <T extends City> void someMethod(List<T[]> objectsList) { 
    List<City[]> myList = (List<City[]>) objectsList; 
} 

Просто пишу это в компилятор с предоставить мне с ошибкой я могу игнорировать - однако во время компиляции компилятор терпит неудачу говоря

Error:(97, 46) error: incompatible types: List<T[]> cannot be converted to List<City[]> where T is a type-variable: T extends City declared in method <T>someMethod(List<T[]>) 

Простое решение для простого запуска весь список и массивы в полученном «objectList» и приведите их по одному за раз, что будет работать (я пробовал это), однако я не уверен, что это правильный способ сделать это ...

+0

Вы можете оставить еще немного code..post в [MCVE] (http://stackoverflow.com/help/mcve) (Minimal Полного Верифицируемого примера) или [SSCCE] (HTTP: //www.sscce .org /) (Short, Self Contained, Правильный пример). – Madhan

+0

* Простое решение состоит в том, чтобы просто запустить весь список и массивы в пределах полученного «objectList» и вывести их по одному за раз, что будет работать *. Я почесываю голову и задаюсь вопросом, что именно вы имеете в виду? Разве вы не думаете, что было бы более разумно, если бы вы сначала сказали нам, что вы хотите делать внутри 'someMethod'? – CKing

+5

@ Мадхан: Это ** является ** MCVE. – Makoto

ответ

2

Это не то, что вы будете хотеть, чтобы сделать часто (так как дженерики и массивы не смешиваются хорошо), но есть некоторые важные вещи, чтобы сделать примечание:

  • T содержит информацию о типе метода. Вы не можете проходить в City во все времена, и в случае, когда вы этого не делаете, Java не может помочь вам.
  • Приведение не будет безопасным из-за того, что дженерики являются инвариантными; вы не можете сказать, что List<City[]> эквивалентен List<T[]>, даже если T extends City.

С этим, что вы можете сделать, чтобы исправить это, используется групповой символ, связанный с общими типами. Используйте их как в объявлении того, что вы принимаете методу, так и в том, что вы храните. Затем вы избегаете приведения, и все безопасно для типов.

public <T extends City> void someMethod(List<? extends T[]> objectsList) { 
    List<? extends T[]> myList = objectsList; 
} 
0

не нужно бросать - просто работайте wi го массива типа T[]. Например, это составляет:

public <T extends City> void someMethod(List<T[]> objectsList) { 
    for (T[] cities : objectsList) { 
     for (City city : cities) { 
      // do something with the city object 
     } 
    } 
} 

код в методе не знает, какой именно подкласс City в массивах, но вы можете присвоить их переменной типа City и рассматривать их как City объектов.


Причина Ваш бросок не работает из-за тот факт, что List<SubType> не является подтип List<Type>.

0

Поскольку в Java массив подобен типу. Ergo, тип City[] полностью отличается от T extends City. Я не уверен, что вы получаете, но что List<T[]> выглядит чрезвычайно изворотливым.

Как использовать Generics

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

public ArrayList<E> getReversedList(ArrayList<E> list) { 
    ArrayList<E> newList = new ArrayList(list.size()); 

    for (int i = 0; i < list.size(); i++) 
     newList.add(list.size() - i, (E) list.get(i)); 

    return newList; 
} 
Смежные вопросы