简体   繁体   English

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

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

For example:例如:

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

This comes up in Java 5 and later if you're using collections without type specifiers (eg, Arraylist() instead of ArrayList<String>() ).如果您使用没有类型说明符的集合(例如, Arraylist()而不是ArrayList<String>() ),这会出现在 Java 5 及更高版本中。 It means that the compiler can't check that you're using the collection in a type-safe way, using generics .这意味着编译器无法检查您是否使用泛型以类型安全的方式使用集合。

To get rid of the warning, you need to be specific about what type of objects you're storing in the collection.要消除警告,您需要具体说明您在集合中存储的对象类型。 So, instead of所以,而不是

List myList = new ArrayList();

use利用

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

In Java 7 you can shorten generic instantiation by using Type Inference .在 Java 7 中,您可以使用Type Inference来缩短泛型实例化。

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

If you do what it suggests and recompile with the "-Xlint:unchecked" switch, it will give you more detailed information.如果您按照它的建议进行操作并使用“-Xlint:unchecked”开关重新编译,它将为您提供更详细的信息。

As well as the use of raw types (as described by the other answers), an unchecked cast can also cause the warning.除了使用原始类型(如其他答案所述)外,未经检查的强制转换也可能导致警告。

Once you've compiled with -Xlint, you should be able to rework your code to avoid the warning.使用 -Xlint 编译后,您应该能够重新编写代码以避免出现警告。 This is not always possible, particularly if you are integrating with legacy code that cannot be changed.这并不总是可行的,尤其是当您与无法更改的遗留代码集成时。 In this situation, you may decide to suppress the warning in places where you know that the code is correct:在这种情况下,您可以决定在您知道代码正确的地方取消警告:

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

For Android Studio, you need to add:对于 Android Studio,您需要添加:

allprojects {

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

    // ...
}

in your project's build.gradle file to know where this error is produced.在项目的 build.gradle 文件中了解此错误的产生位置。

This warning means that your code operates on a raw type, recompile the example with the此警告意味着您的代码在原始类型上运行,请使用

-Xlint:unchecked 

to get the details获取详细信息

like this:像这样:

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 talks about it here: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html docs.oracle.com 在这里谈论它: http ://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

I had 2 years old classes and some new classes.我有 2 年的旧课程和一些新课程。 I solved it in Android Studio as follows:我在Android Studio中解决了如下:

allprojects {

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

}

In my project build.gradle file ( Borzh solution )在我的项目 build.gradle 文件中( Borzh 解决方案

And then if some Metheds is left:然后如果留下一些方法:

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

for example when you call a function that returns Generic Collections and you don't specify the generic parameters yourself.例如,当您调用返回泛型集合的函数并且您自己没有指定泛型参数时。

for a function对于一个函数

List<String> getNames()


List names = obj.getNames();

will generate this error.会产生这个错误。

To solve it you would just add the parameters要解决它,您只需添加参数

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

The "unchecked or unsafe operations" warning was added when java added Generics , if I remember correctly.如果我没记错的话,当 java 添加Generics时添加了“未经检查或不安全的操作”警告。 It's usually asking you to be more explicit about types, in one way or another.它通常要求您以一种或另一种方式更明确地说明类型。

For example.例如。 the code ArrayList foo = new ArrayList();代码ArrayList foo = new ArrayList(); triggers that warning because javac is looking for ArrayList<String> foo = new ArrayList<String>();触发该警告,因为 javac 正在寻找ArrayList<String> foo = new ArrayList<String>();

I just want to add one example of the kind of unchecked warning I see quite often.我只想添加一个我经常看到的未经检查的警告示例。 If you use classes that implement an interface like Serializable, often you will call methods that return objects of the interface, and not the actual class.如果您使用实现像 Serializable 这样的接口的类,您通常会调用返回接口对象的方法,而不是实际的类。 If the class being returned must be cast to a type based on generics, you can get this warning.如果返回的类必须转换为基于泛型的类型,您会收到此警告。

Here is a brief (and somewhat silly) example to demonstrate:这是一个简短(有点愚蠢)的示例来演示:

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() returns an object that implements Serializable. getInstance() 返回一个实现 Serializable 的对象。 This must be cast to the actual type, but this is an unchecked cast.这必须转换为实际类型,但这是未经检查的转换。

The solution would be to use specific type in <> like ArrayList<File> .解决方案是在<>中使用特定类型,例如ArrayList<File>

example:例子:

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

above code generate warning because ArrayList is not of specific type.上面的代码会生成警告,因为ArrayList不是特定类型。

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

above code will do fine.上面的代码会很好。 Only change is in third line after ArrayList . ArrayList之后的第三行中只有更改。

You can keep it in the generic form and write it as:您可以将其保留为通用形式并将其写为:

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

Setting type of ArrayList as Object gives us the advantage to store any type of data.ArrayList的类型设置为Object使我们能够存储任何类型的数据。 You don't need to use -Xlint or anything else.您不需要使用 -Xlint 或其他任何东西。

This warning also could be raised due to new HashMap() or new ArrayList() that is generic type has to be specific otherwise the compiler will generate warning.由于泛型类型的new HashMap()new ArrayList()必须是特定的,因此也可能引发此警告,否则编译器将生成警告。

Please make sure that if you code contains the following you have to change accordingly请确保如果您的代码包含以下内容,则必须进行相应更改

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<>()

I have ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;我有ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value; . . Because value is a complex structure (I want to clean JSON ), there can happen any combinations on numbers, booleans, strings, arrays.因为value是一个复杂的结构(我想清理 JSON ),所以可以在数字、布尔值、字符串、数组上发生任何组合。 So, I used the solution of @Dan Dyer:所以,我使用了@Dan Dyer 的解决方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM