Ах, вы должны знать, что дженерики в java в большинстве случаев являются только синтаксическим сахаром в компиляторе, поэтому, если вы не знаете тип времени выполнения, просто используйте подстановочный или необработанный тип:
MyClass<?> myClass = new MyClass<>();
, MyClass myClass = new MyClass();
Но если пользовательский ввод всегда имеет известный тип, такой как String, тогда вы можете просто сделать:
MyClass<String> myClass = new MyClass<>();
Вы также можете создать универсальный конструктор в своем классе следующим образом:
public class MyClass<T> {
T data;
public <T> MyClass(T data) {this.data = data;}
}
Таким образом, универсальный тип будет относиться к типу данных, которые вы передали ему - но он существует только во время компиляции, во время выполнения Java игнорирует все обобщенные здесь, как это допустимый код Java:
List<String> strings = new ArrayList<>();
strings.add(“a”);
List<Integer> integersKindOf = (List)strings;
integersKindOf.remove(“a”);
Java сохраняет толькоуниверсальный тип полей, суперклассы (class MyMap extends HashMap<String, Integer>
- вы можете получить этот супертип с универсальными параметрами) и методы.Но они не используются во время выполнения, но для чтения этого типа можно использовать отражения.
Для локальных переменных это невозможно и будет бесполезно из-за стирания этого типа.
Существует также общий шаблон для unsafe универсальное приведение, но вы должны быть очень осторожны, когда его использовать:
public <T> T doSomething(String type) {
return (T) Class.forName(type).newInstance();
}
, и тогда это можно использовать так:
ArrayList<Whatever> list = doSomething("java.util.ArrayList");
но этоможет также использоваться следующим образом:
Integer list = doSomething("java.util.ArrayList");
И это вызовет исключение во время выполнения, и именно поэтому это очень небезопасно.