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.
Werkzeugbär
quelle
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<>();
Bill die Eidechse
quelle
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()
{
    //...
}
Dan Dyer
quelle
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.

Borzh
quelle
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

Suganthan Madhavan Pillai
quelle
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()
{
    //...
}
Oskar
quelle
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();
Matt
quelle
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>();

Ryan
quelle
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.

Michael Levy
quelle
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.

Julius
quelle
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.

Mayukh Datta
quelle
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 <> ()

Mahadi Hasan
quelle
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;
CoolMind
quelle