Qu'est-ce qui fait que javac émet l'avertissement «utilise des opérations non contrôlées ou dangereuses»

291

Par exemple:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
porte-outils
la source
Je crée des classes de façon dynamique en utilisant sun.misc.Unsafeet cela donne ces conseils sur la sortie
Davut Gürbüz

Réponses:

392

Cela apparaît dans Java 5 et versions ultérieures si vous utilisez des collections sans spécificateurs de type (par exemple, Arraylist()au lieu de ArrayList<String>()). Cela signifie que le compilateur ne peut pas vérifier que vous utilisez la collection de manière sécurisée, en utilisant des génériques .

Pour vous débarrasser de l'avertissement, précisez simplement quel type d'objets vous stockez dans la collection. Donc, au lieu de

List myList = new ArrayList();

utilisation

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

Dans Java 7, vous pouvez raccourcir l'instanciation générique à l'aide de l' inférence de type .

List<String> myList = new ArrayList<>();
Bill le lézard
la source
Dans Java 7, j'ai reçu le même avertissement même en utilisant Type Interference avec cette collection:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio
13
@Lucio Vous avez toujours besoin de supports angulaires. new ConcurrentHashMap<>()
Bill the Lizard
3
Juste pour souligner, ce n'est pas spécifique aux collections. Vous obtenez l'erreur car le compilateur Java ne peut pas garantir la sécurité des types en général. Par exemple, le même avertissement est généré avec le code suivant: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte
1
-Xlint:uncheckedavec MAVEN
vanduc1102
200

Si vous faites ce qu'il suggère et recompilez avec le commutateur "-Xlint: unchecked", il vous donnera des informations plus détaillées.

En plus de l'utilisation de types bruts (comme décrit par les autres réponses), un cast non contrôlé peut également provoquer l'avertissement.

Une fois que vous avez compilé avec -Xlint, vous devriez pouvoir retravailler votre code pour éviter l'avertissement. Ce n'est pas toujours possible, en particulier si vous intégrez avec du code hérité qui ne peut pas être modifié. Dans cette situation, vous pouvez décider de supprimer l'avertissement aux endroits où vous savez que le code est correct:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Dan Dyer
la source
12
Je souhaite que plus de gens votent pour cette réponse. Je maintiens ma sélection de @Bill the Lizard's answer, mais cette réponse me tient à cœur pour m'avoir montré que la réponse me regardait droit dans le visage dans l'avertissement lui-même ainsi que pour élaborer une autre raison de rencontrer l'erreur.
toolbear
1
Ceci est la réponse ultime!
russellhoff
Cette réponse aurait dû être marquée comme solution! Merci!
Alexander Malygin
19

Pour Android Studio, vous devez ajouter:

allprojects {

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

    // ...
}

dans le fichier build.gradle de votre projet pour savoir où cette erreur est produite.

Borzh
la source
merci, j'ai trouvé d'où venait mon avertissement en ajoutant ceci
JackOuttaBox
J'obtiens cet avertissement et AS montre une classe où il a produit. Et ce n'est pas une erreur, juste un avertissement. Pourquoi devrions-nous ajouter cette option? Un cours à problèmes n'a-t-il pas été montré dans votre situation?
CoolMind
Lol, je viens de répondre à la question, et non , le problème n'apparaît que lorsque vous l'ajoutez.
Borzh
16

Cet avertissement signifie que votre code fonctionne sur un type brut, recompilez l'exemple avec le

-Xlint:unchecked 

pour obtenir les détails

comme ça:

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 en parle ici: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

Suganthan Madhavan Pillai
la source
1
Je pense que oui. Il renvoie à la documentation Oracle pour cet avertissement exact.
Nick Westgate
6

J'avais des classes de 2 ans et quelques nouvelles classes. Je l'ai résolu dans Android Studio comme suit:

allprojects {

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

}

Dans mon projet fichier build.gradle ( solution Borzh )

Et puis s'il reste quelques Metheds:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Oskar
la source
5

par exemple, lorsque vous appelez une fonction qui renvoie des collections génériques et que vous ne spécifiez pas vous-même les paramètres génériques.

pour une fonction

List<String> getNames()


List names = obj.getNames();

générera cette erreur.

Pour le résoudre, il vous suffit d'ajouter les paramètres

List<String> names = obj.getNames();
Mat
la source
5

L'avertissement "opérations non contrôlées ou non sécurisées" a été ajouté lorsque java a ajouté des génériques , si je me souviens bien. Cela vous demande généralement d'être plus explicite sur les types, d'une manière ou d'une autre.

Par exemple. le code ArrayList foo = new ArrayList();déclenche cet avertissement car javac rechercheArrayList<String> foo = new ArrayList<String>();

Ryan
la source
2

Je veux juste ajouter un exemple du type d'avertissement non contrôlé que je vois assez souvent. Si vous utilisez des classes qui implémentent une interface comme Serializable, vous appellerez souvent des méthodes qui renvoient des objets de l'interface, et non la classe réelle. Si la classe renvoyée doit être convertie en un type basé sur des génériques, vous pouvez obtenir cet avertissement.

Voici un exemple bref (et quelque peu stupide) à démontrer:

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 () renvoie un objet qui implémente Serializable. Cela doit être converti en type réel, mais il s'agit d'un cast non contrôlé.

Michael Levy
la source
0

La solution serait d'utiliser un type spécifique <>comme ArrayList<File>.

exemple:

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

le code ci-dessus génère un avertissement car il ArrayListn'est pas de type spécifique.

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

le code ci-dessus fera l'affaire. Seul le changement est en troisième ligne après ArrayList.

Julius
la source
0

Vous pouvez le conserver sous forme générique et l'écrire comme:

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

La définition du type de ArrayList comme Object nous donne l'avantage de stocker tout type de données. Vous n'avez pas besoin d'utiliser -Xlint ou autre chose.

Mayukh Datta
la source
0

Cet avertissement pourrait également être

new HashMap () ou new ArrayList () qui est de type générique doit être spécifique sinon le compilateur générera un avertissement.

Veuillez vous assurer que si votre code contient les éléments suivants, vous devez les modifier en conséquence

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

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

Mahadi Hasan
la source
0

Je l'ai ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Parce que valuec'est une structure complexe (je veux nettoyer JSON ), il peut se produire n'importe quelle combinaison sur des nombres, des booléens, des chaînes, des tableaux. J'ai donc utilisé la solution de @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
CoolMind
la source