2012-06-29 3 views
1

My class TypeRegisterer позволяет клиенту регистрировать параметризованные типы (с тем же параметром, что и TypeRegisterer), а затем создавать их, используя их имя типа raw.Как я должен отражать параметризованный тип, используя guava TypeToken?

Мое текущее решение работает, но у меня есть предупреждение о немедленном броске, и я не уверен, можно ли игнорировать его. Есть лучший способ сделать это?

public class TypeRegisterer<T> { 
    private Map<String, TypeToken<? extends Base<T>>> registeredTypes; 

    public void registerType(TypeToken<? extends Base<T>> typeToken) { 
     registeredTypes.put(typeToken.getRawType().getSimpleName(), typeToken); 
    } 

    public Base<T> initType(String className, T feature) throws Exception { 
     // validation and exception handling removed for brevity 
     TypeToken<? extends Base<T>> ruleType = registeredTypes.get(className); 

     @SuppressWarnings("unchecked") 
     Class<? extends Base<T>> rawType = (Class<? extends Base<T>>) ruleType .getRawType(); 

     return rawType.getConstructor().newInstance(); 
    } 
} 
+0

Что вы делаете, это немного опасно. Предполагая, что вы никогда не ошибаетесь в имени класса, предполагая, что нет двух классов с тем же простым именем, что и расширение «Base» и т. Д., Оно будет работать. Я бы, по крайней мере, проверял такие условия. И, вероятно, избавиться от 'TypeToken' здесь, так как вы фактически используете' Class' в одиночку. Такие методы, как 'initType', всегда возвращающие« правильную вещь », редко бывают правильными. – maaartinus

+0

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

+0

Я был бы более счастлив, просто используя класс для регистрации, но меня отговорили от него предупреждение rawType и предупреждение о немедленном броске, но, глядя на него, по крайней мере, он выглядит более очевидным, что происходит там, поэтому я его изменю - спасибо @ maaartinus – MikeB

ответ

0

Это нормально - параметризованные типы компилируются с type erasure, поэтому информация параметр не доступен во время выполнения.

В runtime, Class<Base<T>> == Class<Base<Integer>> == Class<Base<Double>> и т. Д., Поэтому объект класса, на который ссылается ваша переменная rawType, достаточен для создания экземпляра класса.

+0

Ах, поэтому я мог бы использовать Class вместо TypeToken, но это переместило бы кастинг на метод регистрации и добавит предупреждение типа raw, так что это, вероятно, лучше. – MikeB

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