Що змушує javac видавати попередження "використовує неперевірені або небезпечні операції"


291

Наприклад:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Я створюю кілька класів динамічно, використовуючи sun.misc.Unsafeі даю ці підказки на виході
Davut Gürbüz,

Відповіді:


392

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

Щоб позбутися попередження, просто уточнюйте, який тип об’єктів ви зберігаєте в колекції. Отже, замість

List myList = new ArrayList();

використання

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

У Java 7 ви можете скоротити загальну інстанцію за допомогою Type Inference .

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 ("привіт", "world");
semonte

1
-Xlint:uncheckedз MAVEN
vanduc1102

200

Якщо ви зробите те, що він пропонує, і перекомпілюйте за допомогою перемикача "-Xlint: unconnected", це дасть вам більш детальну інформацію.

Окрім використання сировинних типів (як описано в інших відповідях), неперевірений виступ також може спричинити попередження.

Після компіляції з -Xlint ви маєте можливість переробити свій код, щоб уникнути попередження. Це не завжди можливо, особливо якщо ви інтегруєтесь із застарілим кодом, який неможливо змінити. У цій ситуації ви можете вирішити придушити попередження в місцях, де вам відомо, що код правильний:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}

12
Я б хотів, щоб більше людей підтримали цю відповідь. Я стою на виборі відповіді @Bill Ящірка, але ця відповідь мені близька, бо я показав мені, що відповідь дивився мені прямо в обличчя в самому попередженні, а також роз'яснював ще одну причину виникнення помилки.
toolbear

1
Це остаточна відповідь!
russellhoff

Ця відповідь повинна була бути позначена як рішення! Дякую!
Олександр Малигін

19

Для Android Studio потрібно додати:

allprojects {

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

    // ...
}

у файлі build.gradle вашого проекту, щоб знати, де ця помилка створюється.


дякую, я знайшов, звідки надходить моє попередження, додавши це
JackOuttaBox

Я отримую це попередження, і AS показує клас, де він вироблявся. І це не помилка, а лише попередження. Чому ми повинні додати цю опцію? Чи не був показаний клас проблем у вашій ситуації?
CoolMind

Lol, я просто відповідаю на питання, і ні , проблема не відображається, поки ви цього не додасте.
Борж

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()
{
    //...
}

5

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

для функції

List<String> getNames()


List names = obj.getNames();

призведе до цієї помилки.

Щоб вирішити це, ви просто додати параметри

List<String> names = obj.getNames();

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 як Object дає нам перевагу для зберігання будь-якого типу даних. Вам не потрібно використовувати -Xlint або щось інше.


0

Це попередження також може бути порушено через

новий HashMap () або новий ArrayList (), який є загальним типом, повинен бути специфічним, інакше компілятор генерує попередження.

Будь ласка, переконайтесь, що якщо ваш код містить наведене нижче, його потрібно змінити відповідно

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

новий 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.