Разрешить предупреждение IDE с помощью обобщений, тип Class <?> - PullRequest
2 голосов
/ 31 мая 2009
class Test1<T> {
  Test1(Class<T> type) {}
}

class Test2 extends Test1<Class> {
  Test2() {
    super(Class.class);
  }
}

Это работает, но я предупрежден об использовании необработанного универсального типа в "Test1<Class>". Я понимаю это, но изменение его на "Class<?>" (что должно быть эквивалентно?) Приводит к ошибке компилятора при вызове super () - Class.class, очевидно, имеет тип "Class<Class>" вместо "Class<Class<?>>».

Похоже, что все эти варианты приводят к ошибке компиляции.

Может кто-нибудь увидеть, как решить эту проблему, чтобы я всегда использовал параметр типа с классом и, следовательно, не получал предупреждение IDE? Кажется, лучше так, даже если все работает как есть. Я открыт для изменений в структуре этих двух классов два, пока он сохраняет основное намерение: Test2 - это специальный тип Test1, специализированный для объектов "Class".

Ответы [ 5 ]

2 голосов
/ 01 июня 2009

Ваши предупреждения проистекают из того факта, что Class сам по себе является параметризованным классом: public final class Class<T>. Самый простой способ удалить предупреждения - сделать параметр типа T вместо Class<T>:

class Test1<T> {
    Test1(T type) { Class<?> classType = type.getClass();}
}

class Test2 extends Test1<String> {
    Test2() {
        super("");
    }
}
2 голосов
/ 31 мая 2009

Class и Class<?> не точно эквивалентны. Они семантически эквивалентны, но последний фактически говорит компилятору: «Да, я знаю, что это универсальный тип, но я ничего не знаю о параметре типа». Первый - это просто необработанный тип, который часто может указывать на то, что это старый код, который не был перенесен для использования обобщенных типов.

Это описано в FAQ по обобщению Java - см. Вопрос "В чем разница между неограниченным параметризованным типом с подстановочными знаками и необработанным типом?" в разделе параметризованных типов .

1 голос
/ 31 мая 2009

Это может быть один из тех случаев, когда подходит:

@SuppressWarnings("unchecked")
class Test2 extends Test1<Class> {
  Test2() {
    super(Class.class);
  }
}

Если вы не будете всегда использовать Test1<Class>, я не вижу другого способа разрешить это предупреждение. (Вы, вероятно, получили бы то же предупреждение, если бы вы запустили javac -Xlint:unchecked, но я не уверен в этом.) Проблема в том, что вы обычно (я полагаю) будете использовать ваш класс Test1 с неуниверсальными значениями, но Класс - это обобщенный класс, который принимает объект Class в качестве параметра. Я не вижу в этом никакого пути, поэтому думаю, что лучшим решением будет подавить это конкретное предупреждение, чтобы проблемы real стояли на месте.

1 голос
/ 31 мая 2009

Я использую Java 1.6.0_14, и компилятор не выдает мне никаких предупреждений при компиляции этого кода.

0 голосов
/ 01 июня 2009

Короткий ответ: нет способа указать параметр типа. Это потому, что объект Class (скажем, например, List.class, а не просто Class.class) не понимает этот параметр универсального типа - он стирается во время компиляции.

Моя IDE, Intellij IDEA, выдает то же предупреждение. Это слишком агрессивная среда. Вы можете подавить предупреждение с помощью IDEA (оно генерирует аннотацию @SuppressWarnings), но код для его обхода (как, например, умный обходной путь Роберта Мунто) действительно вводит некоторую неприятную конструкцию, просто чтобы избежать некорректного сообщения IDE - JDK делает не рассматривать этот случай как стирание.

РЕДАКТИРОВАТЬ: Учитывая отрицательный голос, я должен по крайней мере оправдать свое мышление здесь.

Подумайте о следующем:

 List.class

Это представляет объект класса типа:

 Class<List>

Он не может представлять тип:

 Class<List<?>>

потому что неизвестно, будет ли данный список иметь общий параметр или каким он будет. Объект List.class должен представлять все типы, вплоть до параметризации Class.

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

Так что IDE просто слишком чувствительна. Хотя спрашивающий не указал, какую IDE он использует, я вижу такое поведение с Intellij IDEA 8.1.2.

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