是什么导致javac发出“使用未经检查或不安全的操作”警告


291

例如:

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

我正在使用动态创建一些类,sun.misc.Unsafe并在输出中给出了这些提示
DavutGürbüz

Answers:


392

如果您使用的是没有类型说明符的集合(例如,Arraylist()而不是ArrayList<String>()),则在Java 5及更高版本中会出现这种情况。这意味着编译器无法使用泛型以类型安全的方式检查您是否正在使用集合。

要摆脱警告,只需具体说明您要在集合中存储的对象类型。所以,代替

List myList = new ArrayList();

采用

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

在Java 7中,您可以使用Type Inference来缩短泛型实例化。

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

在Java 7中,即使对此类型使用类型干扰,我也收到相同的警告:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio

13
@Lucio您仍然需要尖括号。new ConcurrentHashMap<>()
比尔蜥蜴2014年

3
只是指出,这不是特定于集合的。因为Java编译器通常无法确保类型安全,所以会出现错误。例如,使用以下代码会产生相同的警告:AbstractMap.SimpleEntry <String,String> entry = new AbstractMap.SimpleEntry(“ hello”,“ world”);
2014年

1
-Xlint:uncheckedMAVEN
vanduc1102 '16

200

如果按照建议进行操作并使用“ -Xlint:unchecked”开关重新编译,它将为您提供更多详细信息。

除了使用原始类型(如其他答案所述)外,未经检查的强制类型转换也会引起警告。

使用-Xlint编译后,应该可以重新编写代码以避免警告。这并非总是可能的,尤其是当您与无法更改的旧代码集成时。在这种情况下,您可以决定在知道代码正确的地方禁止显示警告:

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

12
我希望更多的人会赞成这个答案。我支持选择@Bill the Lizard的答案,但是这个答案非常贴切,因为它向我展示了答案在警告本身面前正盯着我,同时阐述了遇到错误的另一个原因。
toolbear 2011年

1
这是最终答案!
russellhoff 2015年

该答案应被标记为解决方案!谢谢!
亚历山大·马林金

19

对于Android Studio,您需要添加:

allprojects {

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

    // ...
}

在项目的build.gradle文件中,以了解在何处产生此错误。


谢谢,我通过添加以下内容找到了我的警告来自哪里
JackOuttaBox

我收到此警告,并且AS显示了产生该错误的类。这不是错误,只是警告。为什么要添加此选项?您的情况是否没有显示问题类别?
CoolMind

大声笑,我只是回答问题,,直到您添加此问题,问题才显示出来。
Borzh

16

此警告意味着您的代码对原始类型进行了操作,请使用

-Xlint:unchecked 

获取详细信息

像这样:

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在这里讨论:http ://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
我认为是的。他链接到Oracle文档以获得此确切警告。
Nick Westgate 2014年

6

我上了2年的课,上了一些新课。我在Android Studio中解决了以下问题:

allprojects {

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

}

在我的项目build.gradle文件中(Borzh解决方案

然后,如果剩下一些方法:

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

5

例如,当您调用一个返回通用集合的函数而您自己没有指定通用参数时。

为了功能

List<String> getNames()


List names = obj.getNames();

将产生此错误。

要解决它,您只需添加参数

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

5

如果我没记错的话,当java添加Generics时,添加了“未经检查或不安全的操作”警告。通常是要求您以一种或另一种方式更明确地说明类型。

例如。该代码ArrayList foo = new ArrayList();触发该警告,因为javac正在寻找ArrayList<String> foo = new ArrayList<String>();


2

我只想添加一个我经常看到的未经检查的警告示例。如果使用实现诸如Serializable之类的接口的类,则通常将调用返回该接口对象而不是实际类的方法。如果必须将返回的类强制转换为基于泛型的类型,则可以获得此警告。

这是一个简短(有点愚蠢)的示例来演示:

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()返回实现Serializable的对象。必须将其强制转换为实际类型,但这是未经检查的强制转换。


0

解决的办法是在<>like中使用特定类型ArrayList<File>

例:

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

上面的代码生成警告,因为ArrayList它不是特定类型。

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

上面的代码会很好。唯一的变化是在之后的第三行ArrayList


0

您可以将其保留为通用形式,并写为:

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

将ArrayList的类型设置为Object可以给我们带来存储任何类型数据的优势。您不需要使用-Xlint或其他任何东西。


0

由于以下原因也可能引发此警告

泛型类型的新HashMap()或新ArrayList()必须特定,否则编译器将生成警告。

请确保如果您的代码包含以下内容,则必须进行相应的更改

新HashMap()=>地图map =新HashMap()新HashMap()=>地图map =新HashMap <>()

new ArrayList()=>列表映射= new ArrayList()new ArrayList()=>列表映射= new ArrayList <>()


0

我有ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;。因为value结构很复杂(我想清除JSON),所以数字,布尔值,字符串,数组上可能会发生任何组合。因此,我使用了@Dan Dyer的解决方案:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.