Как сравнить тип экземпляра объекта с общим типом?
как я могу написать этот код в java?
public class ComponentsManager
{
private List<IComponent> list = new ArrayList<IComponent>();
public <U extends IComponent> U GetComponent() {
for (IComponent component : list) {
if(component instanceof U)
{
return component;
}
}
}
}
но я не могу выполнить instanceof для общих типов. Как я должен это делать?
спасибо.
Ответы
Ответ 1
В принципе, вы не можете этого сделать из-за стирания типа. Обычным обходным путем является передача объекта Class
в качестве параметра; например.
public <U extends IComponent> U GetComponent(Class<U> clazz) {
for (IComponent component : list) {
if (clazz.isInstance(component)) {
return clazz.cast(component);
}
}
}
Вы также можете использовать if (clazz.equals(component.getClass())) { ...
, но это точно соответствует типу... это не то, что делает оператор instanceof
. Оператор instanceof
и метод Class.instanceOf
проверяют, соответствует ли тип значения совместимым присвоением.
Ответ 2
Насколько я знаю, вы не можете. Вам нужно взять объект Class
в качестве параметра:
public <U extends IComponent> U getComponent(Class<U> clazz) {
// ...
if (component.getClass() == clazz) {
return (U) component;
}
}
И назовите его следующим образом:
getComponent(MyComponentImpl.class);
Ответ 3
Общее правило с java - если общий класс должен знать свой общий тип (ы), тогда вам нужно передать подсказку. Общим подходом к проблеме является использование конструктора:
public class ComponentsManager<U extends IComponent> {
private Class<U extends IComponentManeger> genericType = null;
public ComponentsManager<U extends IComponent>(
Class<U extends IComponent> genericType) {
this.genericType = genericType;
}
}
Теперь класс знает свой универсальный тип класса, и вы можете использовать экземпляр класса универсального типа для проверки, если компонент в вашей коллекции соответствует классам общего типа.
Ответ 4
Вы можете попробовать добавить несколько "тестовых" методов:
private static <U extends IComponent> boolean testComponent(U u) {
return true;
}
private static boolean testComponent(Object o) {
return false;
}
Затем используйте testComponent(component)
вместо component instanceof U
.
Пример кода:
import java.util.*;
class IComponent {
}
class T1 extends IComponent {
}
public class Test {
public static <U extends IComponent> boolean testComponent(U u) {
return true;
}
public static boolean testComponent(Object o) {
return false;
}
public static void main(String[] args) {
T1 t = new T1();
System.out.println("hm? " + (testComponent(t) ? "true" : "false"));
}
}
Вывод:
гм? правда
Ответ 5
Точно общий тип не может рассматриваться как нормальная переменная в коде, что затрудняет непосредственное сравнение. Однако рефлексивный класс ParameterizedType
может помочь вам получить экземпляр, представляющий параметризованный тип, который является практически осуществимыми объектами.
Type genericSuperType = object.getClass().getGenericSuperclass()
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments()
if (actualTypeParams[0] instanceof Class) {
((Class) actualTypeParams[0]).isInstance(testingObj);
}
Для получения более подробной информации об использовании на ParameterizedType
и соответствующем TypeVariable
, внутренний класс util, TypeParameterMatcher`, в Netty мог бы ссылаться.