Ответ прост, чтобы сохранить информацию о типе во время выполнения.
Список может действовать как массив, но массив не может действовать как список. Почему то, что вы делаете, работает, потому что вы приводите массив к списку, и, как уже говорилось, список может действовать как массив, так что в этот раз вы в безопасности.
Но кастинг, в общем-то, плохая практика.
Когда вы разыгрываете что-то, на что вы рискуете, вы в основном заставляете компилятор «доверять вам» в том, что вы делаете. Таким образом, вместо того, чтобы компилятор говорил вам, что правильно или неправильно, вы говорите компилятору, что правильно и что неправильно, и это риск, риск поломки. Трудно, потому что , если вы ошибаетесь во время выполнения, мы можем потерпеть крах. Трудно и неуправляемо.
Есть много программистов с множеством мнений, но есть только один компилятор с одним мнением, и мы должны ему доверять.
Итак, вернемся к вопросу, что делаетParameterizedTypeReference<T>.class
на самом деле?
Если вы посмотрите на его конструктор, вы увидите, что он действует как сосуд для информации о типе. Делая new ParameterizedTypeReference<List<Foo.class>> {};
, вы создаете экземпляр анонимного класса при передаче типа. Затем в конструкторе он извлекает информацию о типе из переданного типа и сохраняет ее внутри. Затем в более поздний момент мы можем сделать getType()
, чтобы получить информацию о типе, чтобы мы могли выполнять типизированное «приведение» во время выполнения.
final ParameterizedTypeReference<List<String>> typeRef = new ParameterizedTypeReference<>() {};
final Type type = typeRef.getType();
final String typeName = type.getTypeName();
System.out.println(typeName);
// will print "java.util.List<java.lang.String>"
Этот шаблон называется «Супер-токены», и вы можете прочитатьПодробнее об этом здесь Блог Нила Гафтера - Супер Тип Жетоны