Что заставляет javac выдавать предупреждение «использует непроверенные или небезопасные операции»

291

Например:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
toolbear
источник
Я создаю некоторые классы динамически с помощью, sun.misc.Unsafeи это дает эти подсказки на выходе
Давут Гюрбуз

Ответы:

392

Это происходит в Java 5 и более поздних версиях, если вы используете коллекции без спецификаторов типов (например, Arraylist()вместо ArrayList<String>()). Это означает, что компилятор не может проверить, что вы используете коллекцию безопасным для типов способом, используя дженерики. .

Чтобы избавиться от предупреждения, просто уточните, какой тип объектов вы храните в коллекции. Итак, вместо

List myList = new ArrayList();

использование

List<String> myList = new ArrayList<String>();

В Java 7 вы можете сократить общее создание экземпляров, используя вывод типа .

List<String> myList = new ArrayList<>();
Билл Ящерица
источник
В Java 7 я получил то же предупреждение, даже используя Type Interference с этой коллекцией:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio
13
@Lucio Вам все еще нужны угловые скобки. new ConcurrentHashMap<>()
Билл Ящерица
3
Просто для того, чтобы подчеркнуть, что это не конкретные коллекции. Вы получаете ошибку, потому что компилятор Java не может обеспечить безопасность типов в целом. Например, такое же предупреждение выдается с помощью следующего кода: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
Семь
1
-Xlint:uncheckedс MAVEN
vanduc1102
200

Если вы сделаете то, что он предлагает, и перекомпилируете с ключом "-Xlint: unchecked", он даст вам более подробную информацию.

Помимо использования необработанных типов (как описано в других ответах), неконтролируемое приведение также может вызывать предупреждение.

После того как вы скомпилировали с -Xlint, вы сможете переработать свой код, чтобы избежать предупреждения. Это не всегда возможно, особенно если вы интегрируете с устаревшим кодом, который нельзя изменить. В этой ситуации вы можете решить отключить предупреждение в тех местах, где вы знаете, что код правильный:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Дэн Дайер
источник
12
Я хотел бы, чтобы больше людей поддержали этот ответ. Я поддерживаю свой выбор ответа @Bill the Lizard, но этот ответ мне близок, потому что он показал мне, что ответ смотрел мне прямо в лицо в самом предупреждении, а также объяснил другую причину возникновения ошибки.
toolbear
1
Это окончательный ответ!
russellhoff
Этот ответ должен быть помечен как решение! Спасибо!
Александр Малыгин
19

Для Android Studio необходимо добавить:

allprojects {

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked"
        }
    }

    // ...
}

в файле build.gradle вашего проекта, чтобы узнать, где возникает эта ошибка.

Borzh
источник
спасибо, я нашел, откуда приходит мое предупреждение, добавив это
JackOuttaBox
Я получаю это предупреждение, и КАК показывает класс, где он произвел. И это не ошибка, просто предупреждение. Почему мы должны добавить эту опцию? Разве проблемный класс не показывался в вашей ситуации?
CoolMind
Лол, я просто отвечаю на вопрос, и нет , проблема не отображается, пока ты не добавишь это.
Борж
16

Это предупреждение означает, что ваш код работает с необработанным типом, перекомпилируйте пример с

-Xlint:unchecked 

чтобы получить детали

как это:

javac YourFile.java -Xlint:unchecked

Main.java:7: warning: [unchecked] unchecked cast
        clone.mylist = (ArrayList<String>)this.mylist.clone();
                                                           ^
  required: ArrayList<String>
  found:    Object
1 warning

docs.oracle.com рассказывает об этом здесь: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

Сугантан Мадхаван Пиллаи
источник
1
Я думаю, что это так. Он ссылается на документацию Oracle для этого точного предупреждения.
Ник Вестгейт
6

У меня было 2 года классов и несколько новых классов. Я решил это в Android Studio следующим образом:

allprojects {

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked"
        }
    }

}

В моем проекте файл build.gradle ( решение Борж )

И потом, если осталось несколько Метедов:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Oskar
источник
5

например, когда вы вызываете функцию, которая возвращает общие коллекции, и вы не указываете общие параметры самостоятельно.

для функции

List<String> getNames()


List names = obj.getNames();

сгенерирует эту ошибку.

Для ее решения достаточно добавить параметры

List<String> names = obj.getNames();
Matt
источник
5

Предупреждение о «непроверенных или небезопасных операциях» было добавлено, когда Java добавил Generics , если я правильно помню. Обычно он просит вас быть более ясным о типах, так или иначе.

Например. код ArrayList foo = new ArrayList();вызывает это предупреждение, потому что Javac ищетArrayList<String> foo = new ArrayList<String>();

Райан
источник
2

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

Вот краткий (и несколько глупый) пример для демонстрации:

import java.io.Serializable;

public class SimpleGenericClass<T> implements Serializable {

    public Serializable getInstance() {
        return this;
    }

    // @SuppressWarnings("unchecked")
    public static void main() {

        SimpleGenericClass<String> original = new SimpleGenericClass<String>();

        //  java: unchecked cast
        //    required: SimpleGenericClass<java.lang.String>
        //    found:    java.io.Serializable
        SimpleGenericClass<String> returned =
                (SimpleGenericClass<String>) original.getInstance();
    }
}

getInstance () возвращает объект, который реализует Serializable. Это должно быть приведено к фактическому типу, но это непроверенное приведение.

Майкл Леви
источник
0

Решением будет использование определенного типа в <>лайке ArrayList<File>.

пример:

File curfolder = new File( "C:\\Users\\username\\Desktop");
File[] file = curfolder.listFiles();
ArrayList filename = Arrays.asList(file);

Приведенный выше код генерирует предупреждение, потому что ArrayListне имеет определенного типа.

File curfolder = new File( "C:\\Users\\username\\Desktop");
File[] file = curfolder.listFiles();
ArrayList<File> filename = Arrays.asList(file);

код выше подойдет. Только изменение в третьей строке после ArrayList.

Юлий
источник
0

Вы можете сохранить его в общей форме и записать как:

// list 2 is made generic and can store any type of Object
        ArrayList<Object> list2 = new ArrayList<Object>();

Установка типа ArrayList в качестве объекта дает нам преимущество для хранения любого типа данных. Вам не нужно использовать -Xlint или что-то еще.

Маюх Датта
источник
0

Это предупреждение также может быть вызвано из-за

new HashMap () или новый ArrayList (), который является универсальным типом, должен быть конкретным, иначе компилятор выдаст предупреждение.

Пожалуйста, убедитесь, что если ваш код содержит следующее, вы должны изменить соответствующим образом

новый HashMap () => карта карта = новый HashMap () новый HashMap () => карта карта = новый HashMap <> ()

new ArrayList () => Список карт = новый ArrayList () Новый ArrayList () => Список карт = новый ArrayList <> ()

Махади Хасан
источник
0

У меня есть ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Поскольку valueэто сложная структура (я хочу очистить JSON ), могут быть любые комбинации чисел, логических значений, строк, массивов. Итак, я использовал решение @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
CoolMind
источник