Переменные универсального типа Java

#java #generics

#java #общие типы

Вопрос:

Мой вопрос касается переменных типа, используемых в универсальных классах и методах.

Почему мы не можем сделать что-то подобное T = new T(); или, другими словами, почему мы не можем создать объект типа variable ?

Я знаю, что общая информация стирается во время компиляции, и все преобразуется в
объект, так почему компилятор не предполагает, что это T объект, и не позволяет нам его сконструировать?

Комментарии:

1. Это хороший вопрос. Это иллюстрирует некоторые недостатки, присущие Java Generics, и некоторые утечки в абстракции. Кстати, вы также не можете создать массив T[] по той же причине — удаление типа.

Ответ №1:

Проблема в том, что во время выполнения JVM не знает, какой класс T на самом деле обозначает (эта информация не сохраняется во время выполнения, вот что означает «удаление типа»). Поэтому JVM просто видит, что вы хотите создать новый T , но понятия не имеет, какой конструктор на самом деле вызывать — следовательно, это запрещено.

Существуют обходные пути, но они не будут работать так, как вы предлагаете.

почему компилятор не предполагает, что T является объектом, и не позволяет нам его сконструировать??

Ну, конечно, среда выполнения могла бы просто создать экземпляр java.lang.Object для вас, но это не очень помогло бы, так как вы действительно хотели T .

Комментарии:

1. во-первых, видит ли среда выполнения T или Object, не стирается ли общая информация, ??

2. Я не знаю, что «видит» среда выполнения, поскольку я не знаю, как это реализовано внутренне. Я полагаю, что он просто не видит вообще никакого типа. Вероятно, можно провести различие между случаями, когда в коде действительно записан «Объект», и случаями, когда тип был удален.

Ответ №2:

В дополнение к ответу слеске; если вам нужно создать объекты типа T внутри вашего универсального класса, решение состоит в том, чтобы передать Class<T> ссылку в качестве аргумента либо конструктору, либо методу, которому необходимо создать новые объекты, и использовать этот класс для создания новых экземпляров.

Комментарии:

1. Да, это то, что я имел в виду, говоря «существуют обходные пути». Спасибо, что добавили это :-).

2. Я не одобряю этот подход, но если вам нравится писать действительно хакерский код, вы все равно можете обойти его с помощью отражения. ((ParametrizedType)getClass()).getActualTypeArguments()[0].createNewInstance() . Это предполагает, конечно, конструктор по умолчанию.