Qué causa que javac emita la advertencia "utiliza operaciones no verificadas o inseguras"

291

Por ejemplo:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
herramienta
fuente
Estoy creando algunas clases dinámicamente usando sun.misc.Unsafey está dando estos consejos en la salida
Davut Gürbüz

Respuestas:

392

Esto aparece en Java 5 y versiones posteriores si está utilizando colecciones sin especificadores de tipo (por ejemplo, en Arraylist()lugar de ArrayList<String>()). Significa que el compilador no puede verificar que está utilizando la colección de forma segura, usando genéricos .

Para deshacerse de la advertencia, solo sea específico sobre qué tipo de objetos está almacenando en la colección. Entonces, en lugar de

List myList = new ArrayList();

utilizar

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

En Java 7, puede acortar la creación de instancias genéricas mediante la inferencia de tipos .

List<String> myList = new ArrayList<>();
Bill el lagarto
fuente
En Java 7, recibí la misma advertencia incluso usando Type Interference con esta colección:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio
13
@Lucio Todavía necesitas paréntesis angulares. new ConcurrentHashMap<>()
Bill the Lizard
3
Solo para señalar, esto no es específico de las colecciones. Obtiene el error porque el compilador de Java no puede garantizar la seguridad de los tipos en general. Por ejemplo, se genera la misma advertencia con el siguiente código: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte
1
-Xlint:uncheckedcon MAVEN
vanduc1102
200

Si hace lo que sugiere y vuelve a compilar con el interruptor "-Xlint: desmarcado", le dará información más detallada.

Además del uso de tipos sin formato (como se describe en las otras respuestas), un reparto sin control también puede causar la advertencia.

Una vez que haya compilado con -Xlint, debería poder modificar su código para evitar la advertencia. Esto no siempre es posible, especialmente si se está integrando con código heredado que no se puede cambiar. En esta situación, puede decidir suprimir la advertencia en lugares donde sabe que el código es correcto:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Dan Dyer
fuente
12
Desearía que más personas votaran esta respuesta. Respaldo mi selección de la respuesta de @Bill the Lizard, pero esta respuesta está cerca de mi corazón por mostrarme que la respuesta me estaba mirando directamente a la cara en la advertencia en sí misma, así como elaborar otra razón para encontrar el error.
toolbear
1
Esta es la respuesta final!
russellhoff
¡Esta respuesta debería haber sido marcada como solución! ¡Gracias!
Alexander Malygin
19

Para Android Studio, debe agregar:

allprojects {

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

    // ...
}

en el archivo build.gradle de su proyecto para saber dónde se produce este error.

Borzh
fuente
gracias, descubrí de dónde proviene mi advertencia al agregar esto
JackOuttaBox
Recibo esta advertencia y AS muestra una clase donde se produjo. Y esto no es un error, solo una advertencia. ¿Por qué deberíamos agregar esta opción? ¿No se mostró una clase de problema en su situación?
CoolMind
Lol, acabo de responder la pregunta, y no , el problema no se muestra hasta que agregue esto.
Borzh
16

Esta advertencia significa que su código opera en un tipo sin formato, vuelva a compilar el ejemplo con

-Xlint:unchecked 

para obtener los detalles

Me gusta esto:

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 habla sobre esto aquí: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

Suganthan Madhavan Pillai
fuente
1
Creo que si. Se vincula a la documentación de Oracle para esta advertencia exacta.
Nick Westgate
6

Tuve clases de 2 años y algunas clases nuevas. Lo resolví en Android Studio de la siguiente manera:

allprojects {

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

}

En mi proyecto build.gradle file ( solución de Borzh )

Y luego, si queda algo de Metheds:

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

por ejemplo, cuando llama a una función que devuelve Colecciones genéricas y no especifica los parámetros genéricos usted mismo.

para una función

List<String> getNames()


List names = obj.getNames();

generará este error.

Para resolverlo, simplemente agregaría los parámetros

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

La advertencia de "operaciones no verificadas o inseguras" se agregó cuando Java agregó Genéricos , si no recuerdo mal. Por lo general, le pide que sea más explícito sobre los tipos, de una forma u otra.

Por ejemplo. el código ArrayList foo = new ArrayList();activa esa advertencia porque javac está buscandoArrayList<String> foo = new ArrayList<String>();

Ryan
fuente
2

Solo quiero agregar un ejemplo del tipo de advertencia no verificada que veo con bastante frecuencia. Si usa clases que implementan una interfaz como Serializable, a menudo llamará a métodos que devuelven objetos de la interfaz, y no la clase real. Si la clase que se devuelve debe convertirse a un tipo basado en genéricos, puede obtener esta advertencia.

Aquí hay un breve (y algo tonto) ejemplo para demostrar:

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 () devuelve un objeto que implementa Serializable. Esto se debe convertir al tipo real, pero este es un reparto no verificado.

Michael Levy
fuente
0

La solución sería usar un tipo específico en <>like ArrayList<File>.

ejemplo:

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

el código anterior genera advertencia porque ArrayListno es de tipo específico.

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

el código anterior lo hará bien. Solo el cambio está en la tercera línea después ArrayList.

Julius
fuente
0

Puede mantenerlo en forma genérica y escribirlo como:

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

Establecer el tipo de ArrayList como Object nos da la ventaja de almacenar cualquier tipo de datos. No necesita usar -Xlint ni nada más.

Mayukh Datta
fuente
0

Esta advertencia también podría surgir debido a

nuevo HashMap () o new ArrayList () que es de tipo genérico tiene que ser específico; de lo contrario, el compilador generará una advertencia.

Asegúrese de que si su código contiene lo siguiente, tiene que cambiar en consecuencia

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
fuente
0

Tengo ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Debido a que valuees una estructura compleja (quiero limpiar JSON ), puede ocurrir cualquier combinación de números, booleanos, cadenas, matrices. Entonces, usé la solución de @Dan Dyer:

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