Как сравнить тип экземпляра объекта с общим типом?

как я могу написать этот код в 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 мог бы ссылаться.