2013-04-28 2 views
1

Я немного смущен кодом, приведенным ниже. Проблема в том, что код выглядит так: List < T> имеет тот же тип, что и T. Рассмотрение метода makeList получение параметра типа DTOInt < T> и возвращает список < T> (список T). Класс DTO, реализующий метод T getData() для DTOInt < T>, поэтому у нас есть интерфейс DTOInt, который имеет общее определение T, которое является типом возврата метода getData().Литье родовых Т в список <T>

Так, внутри makeList метод я явный кастинг метода GetData() возвращаемый объект (который имеет тип T) в список < T>. И он компилируется и работает нормально.

О компиляции его ясно - есть очевидное кастинг, но когда он работает, как он не терпит неудачу с ClassCastException на литье в методе makeList()?

interface DTOInt<T>{ 
    T getData(); 
} 

class DTO implements DTOInt<List<List<String[]>>>{ 
    public List<List<String[]>> getData() { 
     String[] arr = {"1.1","1.2","1.3"}; 
     String[] arr1 = {"2.1","2.2","2.3"}; 

     List<String[]> l = new ArrayList<String[]>(); 

     l.add(arr); 
     l.add(arr1); 

     List<List<String[]>> data = new ArrayList<List<String[]>>(); 
      data.add(l); 

     return data; 
    } 

} 

public class Test { 

    static <T> List<T> makeList(DTOInt<T> inp){ 
     T data = inp.getData(); 
     List<T> list = (List<T>) data; 
     return list; 
    } 

    public static void main(String[] args) { 
     System.out.println(makeList(new DTO())); 
    } 
} 

ответ

3

Причина, по которой это работает во время выполнения, состоит в том, что генераторы не существуют во время выполнения, они реализованы исключительно на стороне компилятора. Во время компиляции генерики удаляются процессом, называемым стиранием типа.

Все время выполнения видит, что ваш метод DTO.getData() возвращает результат типа List. Этот результат возвращается из метода makeList(), который, как и в точке выполнения, возвращает List, поэтому среда исполнения счастлива.

Конечно, это работает только потому, что DTO действительно возвращает результат List. Если бы создать второй класс

class DTO2 implements DTOInt<Integer> { ... } 

затем отливку результат DTO2.getData() к List действительно будет сгенерировано исключение.

+0

спасибо, ignaZ! – Nemo

Смежные вопросы