Как избавиться от этого предупреждения дженериков? - PullRequest
2 голосов
/ 12 июля 2010

Я пытаюсь смоделировать универсальный интерфейс, и всякий раз, когда я имитирую его, я получаю это предупреждение:

Выражение типа GenericInterface требует неконтролируемого преобразования для соответствия GenericInterface

Мой интерфейс -

interface GenericInterface<T>{
    public T get();
}

, а мой тест -

@Test
public void testGenericMethod(){
    GenericInterface<String> mockedInterface = EasyMock.createMock(GenericInterface.class);
}

В первой строке теста я получаю предупреждение.

КакЯ удаляю это общее предупреждение?

Ответы [ 4 ]

9 голосов
/ 12 июля 2010

Правильные шаги, чтобы избавиться от предупреждения:

  • Прежде всего, докажите , что непроверенное приведение является безопасным, и документ, подтверждающий
  • Только затем выполните непроверенное приведение и аннотируйте @SuppressWarnings("unchecked") для объявления переменной (не для всего метода)

Так что-то вроде этого:

// this cast is correct because...
@SuppressWarnings("unchecked")
GenericInterface<String> mockedInterface =
    (GenericInterface<String>) EasyMock.createMock(GenericInterface.class);

Указания

Ниже приводится выдержка из Effective Java 2nd Edition: Элемент 24: Устранить непроверенные предупреждения :

  • Исключить все непроверенныепредупреждение о том, что вы можете.
  • Если вы не можете устранить предупреждение и можете доказать, что код, который вызвал предупреждение, безопасны от типов, тогда (и только тогда) подавьте предупреждение с помощью @SuppressWarning("unchecked") аннотации.
  • Всегда используйте аннотацию SuppressWarning на минимально возможной области видимости.
  • Каждый раз, когда вы используете аннотацию @SuppressWarning("unchecked"), добавляйте комментарий, объясняющий, почему это безопасно.

Смежные вопросы


Рефакторинг актерского состава

В большинстве случаев также возможно выполнитьнепроверенный актерский состав внутри обобщенного createMock.Это выглядит примерно так:

static <E> Set<E> newSet(Class<? extends Set> klazz) {
    try {
        // cast is safe because newly instantiated set is empty
        @SuppressWarnings("unchecked")
        Set<E> set = (Set<E>) klazz.newInstance();
        return set;
    } catch (InstantiationException e) {
        throw new IllegalArgumentException(e);
    } catch (IllegalAccessException e) {
        throw new IllegalArgumentException(e);          
    }
}

Тогда в другом месте вы можете просто сделать:

// compiles fine with no unchecked cast warnings!
Set<String> names = newSet(HashSet.class);
Set<Integer> nums = newSet(TreeSet.class);

См. Также

2 голосов
/ 12 июля 2010

Проблема здесь в том, что EasyMock.createMock () будет возвращать объект типа GenericInterface, а не GenericInterface<String>.Вы можете использовать аннотацию @SupressWarnings, чтобы игнорировать предупреждение, или вы можете попробовать явно указать приведение к GenericInterface<String> (я думаю, что это просто дает другое предупреждение.)

0 голосов
/ 12 июля 2010

Если вы действительно застряли на том, чтобы избежать предупреждения компилятора, вы можете объявить интерфейс в своем тесте только для того, чтобы его избежать.

 interface MockGenericInterface extends GenericInterface<String> {}

Тогда вы можете сделать:

 GenericInterface<String> mockedInterface = EasyMock.createMock(MockGenericInterface.class);
0 голосов
/ 12 июля 2010

похоже, обсуждают одно и то же предупреждение ...

Я думаю, @SuppressWarnings может быть ключом к счастью в этом случае

...