Co powoduje, że javac wydaje ostrzeżenie „używa niezaznaczonych lub niebezpiecznych operacji”

291

Na przykład:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
pasek narzędzi
źródło
sun.misc.Unsafe
Tworzę

Odpowiedzi:

392

Pojawia się to w Javie 5 i nowszych, jeśli używasz kolekcji bez specyfikatorów typów (np. Arraylist()Zamiast ArrayList<String>()). Oznacza to, że kompilator nie może sprawdzić, czy używasz kolekcji w sposób bezpieczny dla typu, używając ogólnych .

Aby pozbyć się ostrzeżenia, sprecyzuj, jakiego rodzaju obiekty przechowujesz w kolekcji. Więc zamiast

List myList = new ArrayList();

posługiwać się

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

W Javie 7 możesz skrócić tworzenie instancji za pomocą wnioskowania typu .

List<String> myList = new ArrayList<>();
Bill jaszczurka
źródło
W Javie 7 otrzymałem to samo ostrzeżenie, nawet używając Interferencji typu w tej kolekcji:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio
13
@Lucio Nadal potrzebujesz nawiasów kątowych. new ConcurrentHashMap<>()
Bill the Lizard
3
Dla przypomnienia, nie jest to specyficzne dla kolekcji. Wystąpił błąd, ponieważ kompilator Java nie może ogólnie zapewnić bezpieczeństwa typu. Na przykład to samo ostrzeżenie jest generowane przy użyciu następującego kodu: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry („hello”, „world”);
semonte
1
-Xlint:uncheckedz MAVEN
vanduc1102
200

Jeśli zrobisz to, co sugeruje i zrekompilujesz za pomocą przełącznika „-Xlint: unchecked”, dostarczy ci bardziej szczegółowych informacji.

Oprócz użycia surowych typów (jak opisano w innych odpowiedziach), niezaznaczone rzutowanie może również powodować ostrzeżenie.

Po skompilowaniu z -Xlint powinieneś być w stanie przerobić swój kod, aby uniknąć ostrzeżenia. Nie zawsze jest to możliwe, szczególnie jeśli integrujesz się ze starszym kodem, którego nie można zmienić. W tej sytuacji możesz zdecydować o pominięciu ostrzeżenia w miejscach, w których wiesz, że kod jest poprawny:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Dan Dyer
źródło
12
Chciałbym, aby więcej osób głosowało za odpowiedzią. Opowiadam się za wyborem odpowiedzi @Bill Jaszczurka, ale ta odpowiedź jest mi bliska, ponieważ pokazał mi, że odpowiedź wpatrywała się we mnie w samo ostrzeżenie, a także opracował kolejny powód napotkania błędu.
toolbear
1
To jest ostateczna odpowiedź!
russellhoff,
Ta odpowiedź powinna była zostać oznaczona jako rozwiązanie! Dzięki!
Alexander Malygin
19

W przypadku Androida Studio musisz dodać:

allprojects {

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

    // ...
}

w pliku build.gradle projektu, aby dowiedzieć się, gdzie występuje ten błąd.

Borzh
źródło
dzięki, znalazłem skąd pochodzi moje ostrzeżenie, dodając to
JackOuttaBox
Dostaję to ostrzeżenie i AS pokazuje klasę, w której został wyprodukowany. I to nie jest błąd, tylko ostrzeżenie. Dlaczego powinniśmy dodać tę opcję? Czy w Twojej sytuacji nie pokazano klasy problemów?
CoolMind
Lol, po prostu odpowiadam na pytanie i nie , problem nie jest pokazywany, dopóki go nie dodasz.
Borzh
16

To ostrzeżenie oznacza, że ​​Twój kod działa na typie raw, ponownie skompiluj przykład z

-Xlint:unchecked 

aby uzyskać szczegółowe informacje

lubię to:

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 mówi o tym tutaj: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

Suganthan Madhavan Pillai
źródło
1
Myślę, że tak. Odsyła do dokumentacji Oracle, aby uzyskać dokładne ostrzeżenie.
Nick Westgate,
6

Miałem 2-letnie klasy i kilka nowych klas. Rozwiązałem go w Android Studio w następujący sposób:

allprojects {

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

}

W moim projekcie plik build.gradle ( rozwiązanie Borzha )

A jeśli pozostaną jakieś Metheds:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Oskar
źródło
5

na przykład, gdy wywołujesz funkcję, która zwraca Kolekcje ogólne i nie określasz parametrów ogólnych samodzielnie.

dla funkcji

List<String> getNames()


List names = obj.getNames();

wygeneruje ten błąd.

Aby to rozwiązać, wystarczy dodać parametry

List<String> names = obj.getNames();
Matt
źródło
5

Ostrzeżenie „niesprawdzone lub niebezpieczne operacje” zostało dodane, gdy Java dodała Generics , jeśli dobrze pamiętam. Zwykle prosi o wyraźniejsze określenie typów, w taki czy inny sposób.

Na przykład. kod ArrayList foo = new ArrayList();wyzwala to ostrzeżenie, ponieważ szuka javacArrayList<String> foo = new ArrayList<String>();

Ryan
źródło
2

Chcę tylko dodać jeden przykład tego rodzaju niesprawdzonego ostrzeżenia, które często widuję. Jeśli używasz klas, które implementują interfejs taki jak Serializable, często wywołujesz metody zwracające obiekty interfejsu, a nie rzeczywistą klasę. Jeśli zwracana klasa musi być rzutowana na typ oparty na ogólnych, możesz otrzymać to ostrzeżenie.

Oto krótki (i nieco głupi) przykład, aby zademonstrować:

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 () zwraca obiekt, który implementuje Serializable. To musi być rzutowane na rzeczywisty typ, ale jest to rzut niezaznaczony.

Michael Levy
źródło
0

Rozwiązaniem byłoby użycie określonego typu w <>podobny sposób ArrayList<File>.

przykład:

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

powyższy kod generuje ostrzeżenie, ponieważ ArrayListnie jest określonego typu.

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

powyższy kod będzie w porządku. Tylko zmiana jest w trzeciej linii po ArrayList.

Juliusz
źródło
0

Możesz zachować go w formie ogólnej i zapisać jako:

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

Ustawienie typu ArrayList jako Object daje nam korzyść w zakresie przechowywania dowolnego rodzaju danych. Nie musisz używać -Xlint ani niczego innego.

Mayukh Datta
źródło
0

To ostrzeżenie może zostać również podniesione z powodu

new HashMap () lub new ArrayList (), który jest typem ogólnym, musi być specyficzny, w przeciwnym razie kompilator wygeneruje ostrzeżenie.

Upewnij się, że jeśli kod zawiera następujące elementy, musisz odpowiednio zmienić

new HashMap () => Mapa mapy = nowy HashMap () nowy HashMap () => Mapa mapy = nowy HashMap <> ()

new ArrayList () => List map = new ArrayList () new ArrayList () => Map list = new ArrayList <> ()

Mahadi Hasan
źródło
0

Mam ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Ponieważ valuejest to złożona struktura (chcę wyczyścić JSON ), mogą się zdarzyć dowolne kombinacje liczb, boolanów, ciągów znaków, tablic. Użyłem więc rozwiązania @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
CoolMind
źródło