Cosa causa l'emissione dell'avviso "utilizza operazioni non controllate o non sicure" di javac


291

Per esempio:

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

Sto creando alcune classi in modo dinamico usando sun.misc.Unsafee sta dando questi suggerimenti all'output
Davut Gürbüz

Risposte:


392

Questo si presenta in Java 5 e versioni successive se si utilizzano raccolte senza identificatori di tipo (ad esempio, Arraylist()anziché ArrayList<String>()). Significa che il compilatore non può verificare che stai usando la raccolta in un modo sicuro, usando generici .

Per eliminare l'avvertimento, basta essere specifici sul tipo di oggetti che si stanno archiviando nella raccolta. Quindi, invece di

List myList = new ArrayList();

uso

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

In Java 7 è possibile abbreviare l'istanza generica utilizzando Tipo Inferenza .

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

In Java 7, ho ricevuto lo stesso avvertimento anche usando l' interferenza di tipo con questa raccolta:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio,

13
@Lucio Hai ancora bisogno di parentesi angolari. new ConcurrentHashMap<>()
Bill the Lizard,

3
Solo per sottolineare, questo non è specifico per le raccolte. Viene visualizzato l'errore perché il compilatore Java non può garantire la sicurezza dei tipi in generale. Ad esempio, lo stesso avviso viene prodotto con il seguente codice: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte,

1
-Xlint:uncheckedcon MAVEN
vanduc1102

200

Se fai ciò che suggerisce e ricompila con l'opzione "-Xlint: unchecked", ti darà informazioni più dettagliate.

Oltre all'uso di tipi non elaborati (come descritto dalle altre risposte), un cast non controllato può anche causare l'avvertimento.

Una volta compilato con -Xlint, dovresti essere in grado di rielaborare il codice per evitare l'avvertimento. Questo non è sempre possibile, in particolare se si sta integrando un codice legacy che non può essere modificato. In questa situazione, puoi decidere di sopprimere l'avviso in luoghi in cui sai che il codice è corretto:

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

12
Vorrei che più persone votassero questa risposta. Attendo la mia selezione della risposta di @Bill the Lizard, ma questa risposta mi sta molto a cuore per avermi mostrato che la risposta mi stava fissando in faccia nell'avvertimento stesso, oltre a elaborare un'altra ragione per riscontrare l'errore.
toolbear,

1
Questa è la risposta definitiva!
Russellhoff,

Questa risposta avrebbe dovuto essere contrassegnata come soluzione! Grazie!
Alexander Malygin,

19

Per Android Studio, devi aggiungere:

allprojects {

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

    // ...
}

nel file build.gradle del progetto per sapere dove viene prodotto questo errore.


grazie, ho scoperto da dove proviene il mio avvertimento aggiungendo questo
JackOuttaBox

Ricevo questo avviso e AS mostra una classe in cui è stata prodotta. E questo non è un errore, solo un avvertimento. Perché dovremmo aggiungere questa opzione? Non è stata mostrata una classe di problemi nella tua situazione?
CoolMind,

Lol, rispondo solo alla domanda e no , il problema non viene mostrato fino a quando non lo aggiungi.
Borzh,

16

Questo avviso indica che il codice funziona su un tipo non elaborato, ricompilare l'esempio con

-Xlint:unchecked 

per ottenere i dettagli

come questo:

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 ne parla qui: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
Penso di si. Si collega alla documentazione Oracle per questo avviso esatto.
Nick Westgate,

6

Avevo lezioni di 2 anni e alcune nuove lezioni. L'ho risolto in Android Studio come segue:

allprojects {

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

}

Nel mio progetto build.gradle file ( soluzione Borzh )

E poi se rimangono alcuni Metheds:

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

5

ad esempio quando chiamate una funzione che restituisce Collezioni generiche e non specificate voi stessi i parametri generici.

per una funzione

List<String> getNames()


List names = obj.getNames();

genererà questo errore.

Per risolverlo basta aggiungere i parametri

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

5

L'avviso "operazioni non controllate o non sicure" è stato aggiunto quando java ha aggiunto Generics , se ricordo bene. Di solito ti chiede di essere più esplicito sui tipi, in un modo o nell'altro.

Per esempio. il codice ArrayList foo = new ArrayList();attiva questo avviso perché javac sta cercandoArrayList<String> foo = new ArrayList<String>();


2

Voglio solo aggiungere un esempio del tipo di avviso non controllato che vedo abbastanza spesso. Se usi classi che implementano un'interfaccia come Serializable, spesso chiamerai metodi che restituiscono oggetti dell'interfaccia e non la classe effettiva. Se è necessario eseguire il cast della classe restituita su un tipo basato su generici, è possibile ricevere questo avviso.

Ecco un breve (e un po 'sciocco) esempio da dimostrare:

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 () restituisce un oggetto che implementa Serializable. Deve essere eseguito il cast sul tipo effettivo, ma si tratta di un cast non controllato.


0

La soluzione sarebbe usare un tipo specifico in <>like ArrayList<File>.

esempio:

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

sopra il codice genera un avviso perché ArrayListnon è di tipo specifico.

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

sopra il codice andrà bene. Solo il cambiamento è in terza riga dopo ArrayList.


0

Puoi tenerlo nel modulo generico e scriverlo come:

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

L'impostazione del tipo di ArrayList su Object ci offre il vantaggio di archiviare qualsiasi tipo di dati. Non è necessario utilizzare -Xlint o altro.


0

Questo avviso potrebbe anche essere sollevato a causa di

nuovo HashMap () o nuovo ArrayList () di tipo generico deve essere specifico, altrimenti il ​​compilatore genererà un avviso.

Assicurati che se il codice contiene quanto segue devi cambiare di conseguenza

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

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


0

Io ho ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Poiché valueè una struttura complessa (voglio pulire JSON ), possono verificarsi combinazioni di numeri, valori booleani, stringhe, array. Quindi, ho usato la soluzione di @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.