Điều gì khiến javac phát hành các ứng dụng trên sử dụng các hoạt động không được kiểm soát hoặc không an toàn


291

Ví dụ:

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

Tôi đang tạo một số lớp một cách linh hoạt bằng cách sử dụng sun.misc.Unsafevà nó đưa ra những gợi ý này ở đầu ra
Davut Gürbüz

Câu trả lời:


392

Điều này xuất hiện trong Java 5 trở lên nếu bạn đang sử dụng các bộ sưu tập không có bộ chỉ định kiểu (ví dụ: Arraylist()thay vì ArrayList<String>()). Điều đó có nghĩa là trình biên dịch không thể kiểm tra xem bạn có đang sử dụng bộ sưu tập theo cách an toàn kiểu hay không, sử dụng thuốc generic .

Để thoát khỏi cảnh báo, chỉ cần cụ thể về loại đối tượng bạn đang lưu trữ trong bộ sưu tập. Vì vậy, thay vì

List myList = new ArrayList();

sử dụng

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

Trong Java 7, bạn có thể rút ngắn việc khởi tạo chung bằng cách sử dụng Kiểu suy luận .

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

Trong Java 7, tôi đã nhận được cảnh báo tương tự ngay cả khi sử dụng Kiểu giao thoa với bộ sưu tập này:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio

13
@Lucio Bạn vẫn cần dấu ngoặc góc. new ConcurrentHashMap<>()
Bill Lizard

3
Chỉ cần chỉ ra, đây không phải là bộ sưu tập cụ thể. Bạn gặp lỗi vì trình biên dịch Java không thể đảm bảo an toàn kiểu nói chung. Ví dụ: cảnh báo tương tự được tạo ra với đoạn mã sau: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte

1
-Xlint:uncheckedvới MAVEN
vanduc1102

200

Nếu bạn làm những gì nó gợi ý và biên dịch lại bằng công tắc "-Xlint: unchecked", nó sẽ cung cấp cho bạn thông tin chi tiết hơn.

Cũng như việc sử dụng các loại thô (như được mô tả bởi các câu trả lời khác), một diễn viên không được kiểm tra cũng có thể gây ra cảnh báo.

Khi bạn đã biên dịch bằng -Xlint, bạn sẽ có thể làm lại mã của mình để tránh cảnh báo. Điều này không phải lúc nào cũng có thể, đặc biệt nếu bạn đang tích hợp với mã kế thừa không thể thay đổi. Trong tình huống này, bạn có thể quyết định chặn cảnh báo ở những nơi bạn biết rằng mã là chính xác:

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

12
Tôi muốn nhiều người sẽ nâng cao câu trả lời này. Tôi đứng trước lựa chọn câu trả lời của @Bill the Lizard, nhưng câu trả lời này rất gần với trái tim tôi vì đã cho tôi thấy rằng câu trả lời đang nhìn thẳng vào mặt tôi trong cảnh báo cũng như đưa ra một lý do khác để gặp phải lỗi.
toolbear

1
Đây là câu trả lời cuối cùng!
russellhoff

Câu trả lời này nên được đánh dấu là giải pháp! Cảm ơn!
Alexander Malygin

19

Đối với Android Studio, bạn cần thêm:

allprojects {

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

    // ...
}

trong tệp build.gradle của dự án của bạn để biết lỗi này được tạo ra ở đâu.


cảm ơn, tôi đã tìm thấy cảnh báo của mình đến từ đâu bằng cách thêm vào đây
JackOuttaBox

Tôi nhận được cảnh báo này và AS cho thấy một lớp nơi nó được sản xuất. Và đây không phải là lỗi, chỉ là cảnh báo. Tại sao chúng ta nên thêm tùy chọn này? Không phải là một lớp vấn đề được hiển thị trong tình huống của bạn?
CoolMind

Lol, tôi chỉ trả lời câu hỏi, và không , vấn đề không được hiển thị cho đến khi bạn thêm điều này.
Borzh

16

Cảnh báo này có nghĩa là mã của bạn hoạt động trên một loại thô, biên dịch lại ví dụ với

-Xlint:unchecked 

để có được thông tin chi tiết

như thế này:

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 nói về nó ở đây: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
Tôi nghĩ rằng nó làm. Ông liên kết đến tài liệu của Oracle để cảnh báo chính xác này.
Nick Westgate

6

Tôi đã có 2 năm lớp và một số lớp mới. Tôi đã giải quyết nó trong Android Studio như sau:

allprojects {

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

}

Trong tệp build.gradle dự án của tôi ( giải pháp Borzh )

Và sau đó nếu một số Methedge còn lại:

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

5

ví dụ: khi bạn gọi một hàm trả về Bộ sưu tập Chung và bạn không tự chỉ định các tham số chung.

cho một chức năng

List<String> getNames()


List names = obj.getNames();

sẽ tạo ra lỗi này.

Để giải quyết nó, bạn chỉ cần thêm các tham số

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

5

Cảnh báo "không được kiểm tra hoặc hoạt động không an toàn" đã được thêm khi java thêm Generics , nếu tôi nhớ chính xác. Nó thường yêu cầu bạn rõ ràng hơn về các loại, bằng cách này hay cách khác.

Ví dụ. mã ArrayList foo = new ArrayList();kích hoạt cảnh báo vì javac đang tìm kiếmArrayList<String> foo = new ArrayList<String>();


2

Tôi chỉ muốn thêm một ví dụ về loại cảnh báo không được kiểm tra mà tôi thấy khá thường xuyên. Nếu bạn sử dụng các lớp thực hiện một giao diện như Nối tiếp, thường thì bạn sẽ gọi các phương thức trả về các đối tượng của giao diện chứ không phải lớp thực tế. Nếu lớp được trả về phải được chuyển thành loại dựa trên tổng quát, bạn có thể nhận được cảnh báo này.

Dưới đây là một ví dụ ngắn gọn (và hơi ngớ ngẩn) để chứng minh:

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 () trả về một đối tượng thực hiện Nối tiếp. Điều này phải được chuyển sang loại thực tế, nhưng đây là một diễn viên không được kiểm tra.


0

Giải pháp sẽ là sử dụng loại cụ thể <>nhưArrayList<File> .

thí dụ:

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

ở trên mã tạo cảnh báo vì ArrayListkhông phải là loại cụ thể.

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

mã trên sẽ làm tốt Chỉ thay đổi là trong dòng thứ ba sau ArrayList.


0

Bạn có thể giữ nó ở dạng chung và viết dưới dạng:

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

Cài đặt loại ArrayList làm Object cho chúng ta lợi thế để lưu trữ bất kỳ loại dữ liệu nào. Bạn không cần phải sử dụng -Xlint hoặc bất cứ điều gì khác.


0

Cảnh báo này cũng có thể được nêu ra do

HashMap mới () hoặc ArrayList () mới là loại chung phải cụ thể nếu không trình biên dịch sẽ tạo cảnh báo.

Vui lòng đảm bảo rằng nếu mã của bạn chứa các phần sau, bạn phải thay đổi tương ứng

new HashMap () => Map map = new HashMap () new HashMap () => Map map = new HashMap <> ()

new ArrayList () => List map = new ArrayList () new ArrayList () => List map = new ArrayList <> ()


0

Tôi có ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Vì valuelà một cấu trúc phức tạp (tôi muốn làm sạch JSON ), nên có thể xảy ra bất kỳ kết hợp nào trên các số, booleans, chuỗi, mảng. Vì vậy, tôi đã sử dụng giải pháp của @Dan Dyer:

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.