O que faz com que o javac emita o aviso "usa operações não verificadas ou não seguras"


291

Por exemplo:

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

Estou criando algumas classes dinamicamente usando sun.misc.Unsafee está dando essas dicas na saída
Davut Gürbüz 28/04

Respostas:


392

Isso aparece no Java 5 e posterior se você estiver usando coleções sem especificadores de tipo (por exemplo, em Arraylist()vez de ArrayList<String>()). Isso significa que o compilador não pode verificar se você está usando a coleção de uma maneira segura, usando genéricos .

Para se livrar do aviso, basta ser específico sobre o tipo de objetos que você está armazenando na coleção. Então, ao invés de

List myList = new ArrayList();

usar

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

No Java 7, você pode reduzir a instanciação genérica usando a Inferência de Tipo .

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

No Java 7, recebi o mesmo aviso mesmo usando a interferência de tipo nesta coleção:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio

13
@ Lucio Você ainda precisa de colchetes angulares. new ConcurrentHashMap<>()
Bill o Lagarto

3
Apenas para salientar, isso não é específico de coleções. Você recebe o erro porque o compilador Java não pode garantir a segurança do tipo em geral. Por exemplo, o mesmo aviso é produzido com o seguinte código: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte 8/07/14

1
-Xlint:uncheckedcom MAVEN
vanduc1102

200

Se você fizer o que sugere e recompilar com a opção "-Xlint: unchecked", ele fornecerá informações mais detalhadas.

Além do uso de tipos brutos (conforme descrito pelas outras respostas), uma conversão não verificada também pode causar o aviso.

Depois de compilar com -Xlint, você poderá refazer seu código para evitar o aviso. Isso nem sempre é possível, principalmente se você estiver integrando um código legado que não pode ser alterado. Nessa situação, você pode optar por suprimir o aviso em locais onde você sabe que o código está correto:

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

12
Eu gostaria que mais pessoas votassem nessa resposta. Eu mantenho minha seleção da resposta do @Bill the Lizard, mas esta resposta está próxima do meu coração por me mostrar que a resposta estava me encarando no rosto no próprio aviso, além de elaborar outro motivo para encontrar o erro.
toolbear

1
Esta é a resposta definitiva!
22815 russellhoff #

Esta resposta deveria ter sido marcada como solução! Obrigado!
Alexander Malygin 16/06

19

Para o Android Studio, você precisa adicionar:

allprojects {

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

    // ...
}

no arquivo build.gradle do seu projeto para saber onde esse erro é produzido.


obrigado, eu descobri de onde vem o meu aviso adicionando isto
JackOuttaBox

Recebo esse aviso e o AS mostra uma classe onde foi produzido. E isso não é erro, apenas aviso. Por que devemos adicionar esta opção? Uma classe de problemas não foi mostrada na sua situação?
CoolMind

Lol, acabei de responder à pergunta e não , o problema não é mostrado até você adicionar isso.
Borzh 24/04

16

Esse aviso significa que seu código opera em um tipo bruto, recompile o exemplo com o

-Xlint:unchecked 

para obter os detalhes

como isso:

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

O docs.oracle.com fala sobre isso aqui: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
Eu acho que sim. Ele vincula a documentação do Oracle para esse aviso exato.
Nick Westgate

6

Eu tive aulas de 2 anos e algumas aulas novas. Eu o resolvi no Android Studio da seguinte maneira:

allprojects {

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

}

No meu arquivo build.gradle do projeto ( solução Borzh )

E se sobrar algum Metheds:

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

5

por exemplo, quando você chama uma função que retorna coleções genéricas e não especifica os parâmetros genéricos.

para uma função

List<String> getNames()


List names = obj.getNames();

irá gerar este erro.

Para resolvê-lo, basta adicionar os parâmetros

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

5

O aviso "operações não verificadas ou não seguras" foi adicionado quando o java adicionou Genéricos , se bem me lembro. Geralmente, é pedido que você seja mais explícito sobre os tipos, de uma maneira ou de outra.

Por exemplo. o código ArrayList foo = new ArrayList();aciona esse aviso porque o javac está procurandoArrayList<String> foo = new ArrayList<String>();


2

Eu só quero adicionar um exemplo do tipo de aviso não verificado que vejo com bastante frequência. Se você usar classes que implementam uma interface como Serializable, frequentemente chamará métodos que retornam objetos da interface, e não a classe real. Se a classe que está sendo retornada precisar ser convertida em um tipo baseado em genéricos, você poderá receber este aviso.

Aqui está um breve exemplo (e um tanto bobo) para demonstrar:

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 () retorna um objeto que implementa Serializable. Isso deve ser convertido para o tipo real, mas é um vazamento não verificado.


0

A solução seria usar um tipo específico <>como ArrayList<File>.

exemplo:

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

o código acima gera aviso porque ArrayListnão é do tipo específico.

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

o código acima funcionará bem. Somente a mudança está na terceira linha depois ArrayList.


0

Você pode mantê-lo na forma genérica e escrevê-lo como:

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

Definir o tipo de ArrayList como Object nos dá a vantagem de armazenar qualquer tipo de dados. Você não precisa usar -Xlint ou qualquer outra coisa.


0

Este aviso também pode ser gerado devido a

new HashMap () ou new ArrayList () que é do tipo genérico deve ser específico, caso contrário, o compilador gerará um aviso.

Certifique-se de que, se o código contém o seguinte, você deve alterar de acordo

novo HashMap () => mapa do mapa = new HashMap () novo HashMap () => mapa do mapa = novo HashMap <> ()

new ArrayList () => Listar mapa = new ArrayList () new ArrayList () => Listar mapa = new ArrayList <> ()


0

Eu tenho ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Por valueser uma estrutura complexa (eu quero limpar o JSON ), pode ocorrer qualquer combinação de números, booleanos, seqüências de caracteres e matrizes. Então, usei a solução de @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.