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.
ferramenta
fonte
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<>();
Bill the Lizard
fonte
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()
{
    //...
}
Dan Dyer
fonte
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.

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

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

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

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

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

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

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