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

What causes javac to issue the "uses unchecked or unsafe operations" warning

提问人: 提问时间:10/13/2008 最后编辑:sepp2k 更新时间:6/24/2022 访问量:525994

问:

例如:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Java 泛型 警告

评论

0赞 Davut Gürbüz 4/28/2020
我正在动态创建一些类,并在输出中给出这些提示sun.misc.Unsafe

答:

447赞 Bill the Lizard 10/13/2008 #1

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

若要消除警告,需要具体说明集合中存储的对象类型。所以,而不是

List myList = new ArrayList();

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

在 Java 7 中,您可以使用类型推断来缩短泛型实例化。

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

评论

1赞 Lucio 6/16/2014
在 Java 7 中,即使对这个集合使用 Type Interference,我也收到了相同的警告:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
17赞 Bill the Lizard 6/16/2014
@Lucio 您仍然需要尖括号。new ConcurrentHashMap<>()
3赞 semonte 7/8/2014
需要指出的是,这不是特定于集合的。您收到此错误是因为 Java 编译器通常无法确保类型安全。例如,使用以下代码生成相同的警告: AbstractMap.SimpleEntry<String, String> entry = new AbstractMap.SimpleEntry(“hello”, “world”);
1赞 vanduc1102 3/1/2016
-Xlint:unchecked替换为 MAVEN
0赞 Squared 11/27/2023
>使用没有类型说明符的集合(例如,Arraylist() 而不是 ArrayList<String>()) 什么是“类型说明符”?你的意思是“类型参数”吗?
4赞 Matt 10/13/2008 #2

例如,当您调用返回泛型集合的函数时,您自己不指定泛型参数。

对于函数

List<String> getNames()


List names = obj.getNames();

将生成此错误。

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

List<String> names = obj.getNames();
4赞 Ryan 10/13/2008 #3

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

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

230赞 Dan Dyer 10/13/2008 #4

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

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

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

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

评论

13赞 4/22/2011
我希望更多的人能为这个答案投赞成票。我坚持我选择@Bill蜥蜴的答案,但这个答案很贴近我的心,因为它向我展示了答案在警告本身中直视我的脸,并详细说明了遇到错误的另一个原因。
2赞 Andrew S 3/23/2022
在 Android Studio 中的哪个位置启用或编写此开关?
18赞 Suganthan Madhavan Pillai 5/28/2014 #5

此警告意味着您的代码在原始类型上运行,请使用

-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赞 Nick Westgate 12/3/2014
我认为确实如此。他链接到此确切警告的 Oracle 文档。
1赞 Julius 9/18/2014 #6

解决方案是在 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

3赞 Michael Levy 4/8/2015 #7

我只想添加一个我经常看到的未经检查的警告的例子。如果使用实现接口(如 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赞 Tom 10/2/2023
我认为这是Java的一个缺陷。
34赞 Borzh 11/12/2018 #8

对于 Android Studio,您需要添加:

allprojects {

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

    // ...
}

以了解此错误产生的位置。

评论

0赞 JackOuttaBox 4/14/2020
谢谢,我通过添加这个找到了我的警告来自哪里
0赞 CoolMind 4/23/2020
我收到此警告,AS 显示它产生的类。这不是错误,只是警告。为什么要添加此选项?在你的情况下没有显示问题类吗?
1赞 Borzh 4/24/2020
哈哈,我只是回答这个问题,,在你添加这个之前,问题不会显示出来。
0赞 Mayukh Datta 7/19/2019 #9

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

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

将类型设置为 as 使我们能够存储任何类型的数据。您不需要使用 -Xlint 或其他任何东西。ArrayListObject

8赞 Oskar 9/25/2019 #10

我有 2 年的旧课程和一些新课程。我在Android Studio中解决了它,如下所示:

allprojects {

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

}

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

然后,如果还剩下一些 Metheds:

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

评论

0赞 Tom 10/2/2023
这似乎不适用于 IntelliJ 和 Java20。
-1赞 Mahadi Hasan 12/5/2019 #11

此警告也可能由于泛型类型必须特定而引发,否则编译器将生成警告。new HashMap()new ArrayList()

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

new HashMap() => Map<String,Object> map = new HashMap<String,Object>()
new HashMap() => Map<String,Object> map = new HashMap<>()

new ArrayList() => List<String,Object> map = new ArrayList<String,Object>()
new ArrayList() => List<String,Object> map = new ArrayList<>()
0赞 CoolMind 4/23/2020 #12

我有。因为是一个复杂的结构(我想清理 JSON),所以数字、布尔值、字符串、数组都可以发生任何组合。所以,我使用了@Dan染的溶液:ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;value

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