я могу отражающим образом инстанцировать универсального типа в Java?

У меня была та же проблема. Пробовал переустановить GIT и т. Д. Наконец, я решил удалить и переустановить VS 2015 с обновлением 1, и это исправило проблему.

14
задан sk. 11 December 2008 в 14:10
поделиться

4 ответа

Универсальная информация потеряна во времени выполнения. Нет никакого эквивалента во время выполнения Creator< Строка> .class. Вы могли создать тип между Создателем и StringCreator, который фиксирует универсальный тип:

public interface Creator<T> {
        T create();
}
public interface StringCreator extends Creator<String> { }
public class StringCreatorImpl implements StringCreator  {
        public String create() { return new String(); }
}
public class FancyStringCreator implements StringCreator  {
        public String create() { return new StringBuffer().toString(); }
}
public static void main(String[] args) throws Exception {
        Class<?> someClass = Class.forName(args[0]);
        Class<? extends StringCreator> creatorClass = someClass.asSubclass(StringCreator.class);
        Constructor<? extends StringCreator> creatorCtor = creatorClass.getConstructor((Class<?>[]) null);
        Creator<String> creator = creatorCtor.newInstance((Object[]) null);
}

, Но конечно Вы теряете немного гибкости, потому что Вы не можете использовать следующий класс создателя:

public class AnotherCreator implements Creator<String> {
    public String create() { return ""; }
}
11
ответ дан 1 December 2019 в 13:34
поделиться

Это сделает то, что Вы пытаетесь сделать при обеспечении безопасности типов. Нет никакого способа избежать предупреждения непроверенного, но проверка типа, сделанная здесь, выравнивает по ширине свое подавление.

  public static void main(String[] args)
    throws Exception
  {
    Class<? extends Creator<String>> clz = load(argv[0], String.class);
    Constructor<? extends Creator<String>> ctor = clz.getConstructor();
    Creator<String> creator = ctor.newInstance();
    System.out.println(creator.create());
  }

  public static <T> Class<? extends Creator<T>> load(String fqcn, Class<T> type)
    throws ClassNotFoundException
  {
    Class<?> any = Class.forName(fqcn);
    for (Class<?> clz = any; clz != null; clz = clz.getSuperclass()) {
      for (Object ifc : clz.getGenericInterfaces()) {
        if (ifc instanceof ParameterizedType) {
          ParameterizedType pType = (ParameterizedType) ifc;
          if (Creator.class.equals(pType.getRawType())) {
            if (!pType.getActualTypeArguments()[0].equals(type))
              throw new ClassCastException("Class implements " + pType);
            /* We've done the necessary checks to show that this is safe. */
            @SuppressWarnings("unchecked")
            Class<? extends Creator<T>> creator = (Class<? extends Creator<T>>) any;
            return creator;
          }
        }
      }
    }
    throw new ClassCastException(fqcn + " does not implement Creator<String>");
  }

основное ограничение, которого необходимо придерживаться, - то, что класс в иерархии должен указать параметр типа. Например class MyCreator implements Creator<String>. Вы не можете использовать его с class GenericCreator<T> implements Creator<T>.

Это в настоящее время не обрабатывает допустимый случай, где Вы создаете новый интерфейс interface StringCreatorIfc extends Creator<String> и имеете реализацию класса это. Это могло быть улучшено, чтобы сделать это, но я оставлю это как осуществление для наклоненных.

5
ответ дан 1 December 2019 в 13:34
поделиться

Вам не нужна та строка. И при этом Вам не нужен конструктор, поскольку Вы просто используете по умолчанию. Просто инстанцируйте класса непосредственно:

public static void main(String[] args) throws Exception {
        Class<?> someClass = Class.forName(args[0]);
        Creator<String> creator = (Creator<String>) someClass.newInstance();
}

, Если Вы настаиваете, Вы только сможете стать промежуточными там:

public static void main(String[] args) throws Exception {
    Class<?> someClass = Class.forName(args[0]);
    Class<? extends Creator> creatorClass = someClass.asSubclass(Creator.class);
    Constructor<? extends Creator> creatorCtor = creatorClass.getConstructor((Class<?>[]) null);
    Creator<String> creator = (Creator<String>) creatorCtor.newInstance((Object[]) null);
}
3
ответ дан 1 December 2019 в 13:34
поделиться

Не совсем уверенный, почему Вы используете дженерики здесь.

инстанцирование объекта с помощью отражения предложило бы общее использование, но по-видимому Вы собираетесь звонить create в какой-то момент и присвоить результат String, иначе почему использование дженерики для управления типом возврата.

, Но если Вы записали следующую реализацию Создателя:

public class IntegerCreator implements Creator<Integer> 
{
  public Integer create() 
  { 
    ...
  }
}

И передал его в как аргумент, который Вы получите ClassCastException при вызове create и присвоении результата.

-1
ответ дан 1 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: