Was bewirkt, dass javac die Warnung "Verwendet ungeprüfte oder unsichere Vorgänge" ausgibt


291

Beispielsweise:

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

Ich erstelle einige Klassen dynamisch mit sun.misc.Unsafeund es gibt diese Hinweise auf die Ausgabe
Davut Gürbüz

Antworten:


392

Dies tritt in Java 5 und höher auf, wenn Sie Sammlungen ohne Typspezifizierer verwenden (z. B. Arraylist()anstelle von ArrayList<String>()). Dies bedeutet, dass der Compiler nicht überprüfen kann, ob Sie die Sammlung mithilfe von Generika typsicher verwenden .

Um die Warnung zu entfernen, müssen Sie nur genau angeben, welche Art von Objekten Sie in der Sammlung speichern. Also statt

List myList = new ArrayList();

verwenden

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

In Java 7 können Sie die generische Instanziierung mithilfe von Typinferenz verkürzen .

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

In Java 7 erhielt ich die gleiche Warnung, selbst wenn ich Type Interference mit dieser Sammlung verwendete:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio

13
@ Lucio Du brauchst noch spitze Klammern. new ConcurrentHashMap<>()
Bill the Lizard

3
Nur um darauf hinzuweisen, dies ist nicht sammlungsspezifisch. Sie erhalten den Fehler, weil der Java-Compiler die Typensicherheit im Allgemeinen nicht gewährleisten kann. Dieselbe Warnung wird beispielsweise mit dem folgenden Code erzeugt: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("Hallo", "Welt");
Semonte

1
-Xlint:uncheckedmit MAVEN
vanduc1102

200

Wenn Sie die Vorschläge ausführen und mit dem Schalter "-Xlint: unchecked" neu kompilieren, erhalten Sie detailliertere Informationen.

Neben der Verwendung von Rohtypen (wie in den anderen Antworten beschrieben) kann eine ungeprüfte Besetzung auch die Warnung auslösen.

Sobald Sie mit -Xlint kompiliert haben, sollten Sie in der Lage sein, Ihren Code zu überarbeiten, um die Warnung zu vermeiden. Dies ist nicht immer möglich, insbesondere wenn Sie in Legacy-Code integrieren, der nicht geändert werden kann. In dieser Situation können Sie die Warnung an Stellen unterdrücken, an denen Sie wissen, dass der Code korrekt ist:

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

12
Ich wünschte, mehr Menschen würden diese Antwort positiv bewerten. Ich stehe zu meiner Auswahl der Antwort von @Bill the Lizard, aber diese Antwort liegt mir sehr am Herzen, weil sie mir zeigt, dass die Antwort mich in der Warnung selbst direkt ins Gesicht gestarrt hat, und einen weiteren Grund für die Feststellung des Fehlers herausgearbeitet hat.
Toolbear

1
Dies ist die ultimative Antwort!
Russellhoff

Diese Antwort sollte als Lösung markiert sein! Vielen Dank!
Alexander Malygin

19

Für Android Studio müssen Sie Folgendes hinzufügen:

allprojects {

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

    // ...
}

In der build.gradle-Datei Ihres Projekts erfahren Sie, wo dieser Fehler auftritt.


danke, ich habe herausgefunden, woher meine Warnung kommt, indem ich dies hinzufügte
JackOuttaBox

Ich bekomme diese Warnung und AS zeigt eine Klasse, in der sie produziert wurde. Und das ist kein Fehler, nur eine Warnung. Warum sollten wir diese Option hinzufügen? Wurde in Ihrer Situation nicht eine Problemklasse gezeigt?
CoolMind

Lol, ich beantworte nur die Frage und nein , das Problem wird erst angezeigt, wenn Sie dies hinzufügen.
Borzh

16

Diese Warnung bedeutet, dass Ihr Code mit einem Rohtyp arbeitet. Kompilieren Sie das Beispiel mit dem

-Xlint:unchecked 

um die Details zu bekommen

so was:

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 spricht hier darüber: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
Ich denke schon. Für genau diese Warnung verweist er auf die Oracle-Dokumentation.
Nick Westgate

6

Ich hatte 2 Jahre alte Klassen und einige neue Klassen. Ich habe es in Android Studio wie folgt gelöst:

allprojects {

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

}

In meinem Projekt build.gradle Datei ( Borzh Lösung )

Und wenn dann noch ein paar Metheds übrig sind:

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

5

Zum Beispiel, wenn Sie eine Funktion aufrufen, die generische Sammlungen zurückgibt, und die generischen Parameter nicht selbst angeben.

für eine Funktion

List<String> getNames()


List names = obj.getNames();

wird diesen Fehler erzeugen.

Um es zu lösen, fügen Sie einfach die Parameter hinzu

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

5

Die Warnung "ungeprüfte oder unsichere Vorgänge" wurde hinzugefügt, als Java Generics hinzufügte , wenn ich mich richtig erinnere. Normalerweise werden Sie gebeten, auf die eine oder andere Weise expliziter über Typen zu sprechen.

Beispielsweise. Der Code ArrayList foo = new ArrayList();löst diese Warnung aus, weil Javac suchtArrayList<String> foo = new ArrayList<String>();


2

Ich möchte nur ein Beispiel für die Art von ungeprüfter Warnung hinzufügen, die ich ziemlich oft sehe. Wenn Sie Klassen verwenden, die eine Schnittstelle wie Serializable implementieren, rufen Sie häufig Methoden auf, die Objekte der Schnittstelle und nicht die eigentliche Klasse zurückgeben. Wenn die zurückgegebene Klasse in einen generischen Typ umgewandelt werden muss, können Sie diese Warnung erhalten.

Hier ist ein kurzes (und etwas albernes) Beispiel, um zu demonstrieren:

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 () gibt ein Objekt zurück, das Serializable implementiert. Dies muss auf den tatsächlichen Typ umgewandelt werden, dies ist jedoch eine ungeprüfte Umwandlung.


0

Die Lösung wäre, einen bestimmten Typ in <>like zu verwenden ArrayList<File>.

Beispiel:

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

Der obige Code generiert eine Warnung, da ArrayListes sich nicht um einen bestimmten Typ handelt.

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

Der obige Code reicht aus. Nur die Änderung erfolgt in der dritten Zeile danach ArrayList.


0

Sie können es in der generischen Form behalten und schreiben als:

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

Wenn Sie den ArrayList-Typ als Objekt festlegen, können Sie jeden Datentyp speichern. Sie müssen -Xlint oder etwas anderes nicht verwenden.


0

Diese Warnung könnte auch aufgrund von ausgelöst werden

new HashMap () oder new ArrayList (), ein generischer Typ, muss spezifisch sein, sonst generiert der Compiler eine Warnung.

Bitte stellen Sie sicher, dass Sie entsprechend ändern müssen, wenn Ihr Code Folgendes enthält

neue HashMap () => Map map = neue HashMap () neue HashMap () => Map map = neue HashMap <> ()

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


0

Ich habe ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Da valuees sich um eine komplexe Struktur handelt (ich möchte JSON bereinigen ), können beliebige Kombinationen für Zahlen, Boolesche Werte, Zeichenfolgen und Arrays auftreten. Also habe ich die Lösung von @Dan Dyer verwendet:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.