Apa yang menyebabkan javac mengeluarkan peringatan "menggunakan operasi yang tidak dicentang atau tidak aman"

291

Sebagai contoh:

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
toolbear
sumber
Saya membuat beberapa kelas secara dinamis menggunakan sun.misc.Unsafedan itu memberikan petunjuk ini pada output
Davut Gürbüz

Jawaban:

392

Ini muncul di Java 5 dan yang lebih baru jika Anda menggunakan koleksi tanpa tipe penentu (mis., Arraylist()Bukannya ArrayList<String>()). Ini berarti bahwa kompiler tidak dapat memeriksa bahwa Anda menggunakan koleksi dengan cara yang aman, menggunakan obat generik .

Untuk menghilangkan peringatan, cukup spesifik tentang jenis objek apa yang Anda simpan dalam koleksi. Jadi, bukannya

List myList = new ArrayList();

menggunakan

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

Di Java 7 Anda dapat mempersingkat instantiasi umum dengan menggunakan Type Inference .

List<String> myList = new ArrayList<>();
Bill the Lizard
sumber
Di Java 7, saya mendapat peringatan yang sama bahkan menggunakan Type Interference dengan koleksi ini:ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio
13
@ Lucio Anda masih membutuhkan kurung sudut. new ConcurrentHashMap<>()
Bill the Lizard
3
Hanya untuk menunjukkan, ini bukan koleksi khusus. Anda mendapatkan kesalahan karena Java compiler tidak dapat memastikan keamanan tipe secara umum. Misalnya, peringatan yang sama dihasilkan dengan kode berikut: AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ("hello", "world");
semonte
1
-Xlint:uncheckeddengan MAVEN
vanduc1102
200

Jika Anda melakukan apa yang disarankan dan mengkompilasi ulang dengan sakelar "-Xlint: unchecked", itu akan memberi Anda informasi yang lebih terperinci.

Seperti halnya penggunaan jenis mentah (seperti yang dijelaskan oleh jawaban lain), gips yang tidak dicentang juga dapat menyebabkan peringatan.

Setelah dikompilasi dengan -Xlint, Anda harus dapat mengolah kode Anda untuk menghindari peringatan. Ini tidak selalu memungkinkan, terutama jika Anda mengintegrasikan dengan kode lawas yang tidak dapat diubah. Dalam situasi ini, Anda dapat memutuskan untuk menekan peringatan di tempat-tempat di mana Anda tahu bahwa kode itu benar:

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}
Dan Dyer
sumber
12
Saya berharap lebih banyak orang akan membenarkan jawaban ini. Saya mendukung pilihan @Bill the Lizard, tetapi jawaban ini dekat dengan hati saya karena menunjukkan kepada saya bahwa jawabannya menatap langsung ke wajah saya dalam peringatan itu sendiri serta menguraikan alasan lain untuk menemukan kesalahan.
toolbear
1
Ini jawaban pamungkas!
russellhoff
Jawaban ini seharusnya ditandai sebagai solusi! Terima kasih!
Alexander Malygin
19

Untuk Android Studio, Anda perlu menambahkan:

allprojects {

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

    // ...
}

di file build.gradle proyek Anda untuk mengetahui di mana kesalahan ini terjadi.

Borzh
sumber
terima kasih, saya menemukan dari mana peringatan saya berasal dengan menambahkan ini
JackOuttaBox
Saya mendapatkan peringatan ini dan AS menunjukkan kelas di mana ia diproduksi. Dan ini bukan kesalahan, hanya peringatan. Mengapa kita harus menambahkan opsi ini? Bukankah kelas masalah ditunjukkan dalam situasi Anda?
CoolMind
Lol, saya hanya menjawab pertanyaan, dan tidak , masalahnya tidak ditampilkan sampai Anda menambahkan ini.
Borzh
16

Peringatan ini berarti bahwa kode Anda beroperasi pada tipe mentah, kompilasi ulang contoh dengan

-Xlint:unchecked 

untuk mendapatkan detailnya

seperti ini:

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 membicarakannya di sini: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

Suganthan Madhavan Pillai
sumber
1
Saya kira begitu. Ia menautkan ke dokumentasi Oracle untuk peringatan yang tepat ini.
Nick Westgate
6

Saya memiliki kelas 2 tahun dan beberapa kelas baru. Saya menyelesaikannya di Android Studio sebagai berikut:

allprojects {

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

}

Dalam file build.gradle proyek saya ( solusi Borzh )

Dan kemudian jika beberapa Metheds tersisa:

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

misalnya ketika Anda memanggil fungsi yang mengembalikan Koleksi Generik dan Anda tidak menentukan sendiri parameter generik.

untuk suatu fungsi

List<String> getNames()


List names = obj.getNames();

akan menghasilkan kesalahan ini.

Untuk mengatasinya Anda hanya perlu menambahkan parameter

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

Peringatan "operasi tidak dicentang atau tidak aman" ditambahkan ketika java menambahkan Generics , jika saya ingat dengan benar. Biasanya meminta Anda untuk lebih eksplisit tentang jenis, dengan satu atau lain cara.

Sebagai contoh. kode ArrayList foo = new ArrayList();memicu peringatan itu karena javac sedang mencariArrayList<String> foo = new ArrayList<String>();

Ryan
sumber
2

Saya hanya ingin menambahkan satu contoh jenis peringatan yang tidak dicentang yang sering saya lihat. Jika Anda menggunakan kelas yang mengimplementasikan antarmuka seperti Serializable, seringkali Anda akan memanggil metode yang mengembalikan objek antarmuka, dan bukan kelas yang sebenarnya. Jika kelas yang dikembalikan harus dilemparkan ke tipe berdasarkan generik, Anda bisa mendapatkan peringatan ini.

Berikut adalah contoh singkat (dan agak konyol) untuk diperagakan:

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 () mengembalikan objek yang mengimplementasikan Serializable. Ini harus dilemparkan ke jenis yang sebenarnya, tetapi ini adalah pemain yang tidak dicentang.

Michael Levy
sumber
0

Solusinya adalah dengan menggunakan tipe spesifik <>seperti ArrayList<File>.

contoh:

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

kode di atas menghasilkan peringatan karena ArrayListbukan tipe tertentu.

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

kode di atas akan baik-baik saja. Hanya perubahan yang ada di baris ketiga setelahnya ArrayList.

Julius
sumber
0

Anda dapat menyimpannya dalam bentuk umum dan menuliskannya sebagai:

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

Mengatur jenis ArrayList sebagai Objek memberi kita keuntungan untuk menyimpan semua jenis data. Anda tidak perlu menggunakan -Xlint atau yang lainnya.

Mayukh Datta
sumber
0

Peringatan ini juga dapat dinaikkan karena

HashMap baru () atau ArrayList baru () yang merupakan tipe generik harus spesifik jika tidak, kompiler akan menghasilkan peringatan.

Harap pastikan bahwa jika kode Anda berisi yang berikut, Anda harus mengubahnya sesuai

HashMap baru () => Peta peta = HashMap baru () HashMap baru () => Peta peta = HashMap baru <> ()

ArrayList baru () => Daftar peta = ArrayList baru () ArrayList baru () => Daftar peta = ArrayList baru <> ()

Mahadi Hasan
sumber
0

Saya punya ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. Karena valuemerupakan struktur yang kompleks (saya ingin membersihkan JSON ), dapat terjadi kombinasi pada angka, boolean, string, array. Jadi, saya menggunakan solusi @Dan Dyer:

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