Как сравнить тип экземпляра объекта с универсальным типом? - PullRequest
14 голосов
/ 17 мая 2011

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

Ответы [ 5 ]

22 голосов
/ 17 мая 2011

В основном вы не можете сделать это из-за стирания типа. Обычный обходной путь - передать объект 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 голосов
/ 17 мая 2011

Вы можете попробовать добавить пару «тестовых» методов:

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"));
  }
}

Выход:

гм? правда

2 голосов
/ 17 мая 2011

Общее правило с 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;
  }

}

Теперь класс знает, что это класс универсального типа, и вы можете использовать экземпляр класса универсального типа, чтобы проверить, соответствует ли компонент в вашей коллекции универсальному типу классов.

2 голосов
/ 17 мая 2011

Насколько я знаю, ты не можешь. Вам нужно будет взять Class объект в качестве параметра:

public <U extends IComponent> U getComponent(Class<U> clazz) {
    // ...
    if (component.getClass() == clazz) {
        return (U) component;
    }
}

И назовите это так:

getComponent(MyComponentImpl.class);
0 голосов
/ 18 августа 2017

Точно универсальный тип не может рассматриваться как нормальная переменная в коде, что затрудняет прямое сравнение.Однако рефлексивный класс ParameterizedType может помочь вам получить экземпляр, представляющий параметризованный тип, который в основном является практически осуществимым объектом.

Type genericSuperType = object.getClass().getGenericSuperclass()
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments()
if (actualTypeParams[0] instanceof Class) {
    ((Class) actualTypeParams[0]).isInstance(testingObj);
}

Для получения дополнительной информации об использовании при ParameterizedType и соответствующем TypeVariableна внутренний класс утилит TypeParameterMatcher` в Netty можно ссылаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...