Определить переведенный тип для обобщений во время выполнения - PullRequest
1 голос
/ 22 декабря 2011

Мой вопрос точно такой же, как у здесь . Просто я хочу сделать это на Java.

Предположим, я хочу создать список как:

List<a_type> myList = new ArrayList<a_type>();

Проблема в том, что то, что было бы a_type, решается на основе условия. Два возможных типа совершенно не связаны, не имея общего суперкласса, но Object. Моя проблема будет решена, если я смогу сохранить тип в переменной requiredType и использовать его как List<requiredType>. Я не уверен, что я просто жадный, глупый или невежественный, желая этого, но это ситуация.

Хотя это и не важно, но сценарий, который объясняет, зачем мне это нужно, объясняется здесь .


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

Ответы [ 4 ]

2 голосов
/ 22 декабря 2011

Единственный эффективный (если «рискованный») способ, которым я мог бы это сделать, - это что-то вроде:

     List<?> myList = new ArrayList<?> ();

     /* … */

     final Object o = myList.get (0);

     if (o instanceof OneType) {
           OneType o1 = (OneType)o;
           /* … */
     } else if (o instanceof OtherType) {
           OtherType o2 = (OtherType)o;
           /* … */
     } else {
           throw new RuntimeException ("unexpected type found in list…");
     }

Возможно, вы захотите засорить этот код с помощью @ SuppressWarnings

Возможно, лучшей (?) Идеей было бы реализовать по крайней мере «интерфейс маркера» (без, возможно, каких-либо методов) в обоих типах и использовать это как общность.

     public interface CanBeAddedToDualTypedList { };
     public class OneType implements CanBeAddedToDualTypeList { … };
     public class OtherType implements CanBeAddedToDualTypeList { … };


     List<CanBeAddedToDualTypedList> myList = 
                     new ArrayList<CanBeAddedToDualTypedList> ()

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

2 голосов
/ 22 декабря 2011

Это невозможно в Java из-за стирания типов и из-за того, что обобщенные элементы ограничены только временем компиляции.

например.

List<Integer> integers = new ArrayList<Integer>();

Во время компиляции, когда стирание типов завершено, становится

List integers = new ArrayList();

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

0 голосов
/ 22 декабря 2011

Вы можете сохранить объект a_type.class, в то время как это не поможет вам с обобщениями, его можно использовать для добавления дополнительных проверок типов во время выполнения class.cast(...).

Универсальные типы не поддерживают типизацию во время выполнения, сам универсальный тип не существует во время выполнения. C # имеет класс времени выполнения для каждого общего типа List<String> отличается от List<int>. В Java это не так, когда List<String> и List<Integer> ухудшаются до List во время выполнения.

AFAIK (никогда не пробовал), расширяя класс Generic, сохраняет тип где-то доступный для отражения class StringList extends List<String>{}, StringList запоминает тип Generic, используемый для расширения List.

0 голосов
/ 22 декабря 2011

Обобщение Java недоступно во время выполнения, поэтому невозможно с помощью java

Выполните поиск "Erasure Type" в Google, и вы поймете его лучше.

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