Pertanyaan Cara mentransmisikan List ke List

Ini tidak dikompilasi, saran apa pun dihargai.

 ...
  List<Object> list = getList();
  return (List<Customer>) list;

Compiler mengatakan: tidak dapat melakukan cast List<Object> untuk List<Customer>


75
2017-12-16 21:23


asal


Jawaban:


Anda selalu dapat mentransmisikan objek apa pun ke jenis apa pun dengan mengarahkannya ke Objek terlebih dahulu. dalam kasus Anda:

(List<Customer>)(Object)list; 

Anda harus yakin bahwa pada saat runtime, daftar tidak berisi apa pun kecuali objek Pelanggan.

Kritik mengatakan bahwa pengecoran semacam itu menunjukkan sesuatu yang salah dengan kode Anda; Anda harus dapat mengubah deklarasi jenis Anda untuk menghindarinya. Tetapi generik Java terlalu rumit, dan itu tidak sempurna. Kadang-kadang Anda tidak tahu apakah ada solusi yang cukup untuk memuaskan compiler, meskipun Anda tahu dengan baik jenis runtime dan Anda tahu apa yang Anda coba lakukan adalah aman. Dalam hal ini, cukup lakukan pengecoran mentah sesuai kebutuhan, sehingga Anda dapat meninggalkan pekerjaan untuk rumah.


111
2017-12-17 10:42



Itu karena meskipun seorang Pelanggan adalah Objek, Daftar Pelanggan bukan sebuah Daftar Objek. Jika itu, maka Anda bisa meletakkannya apa saja objek dalam daftar Pelanggan.


34
2017-12-16 21:25



Bergantung pada kode Anda yang lain, jawaban terbaik dapat bervariasi. Mencoba:

List<? extends Object> list = getList();
return (List<Customer>) list;

atau

List list = getList();
return (List<Customer>) list;

Tetapi ada dalam pikiran itu tidak dianjurkan untuk melakukan cast seperti dicentang.


28
2017-12-16 21:28



Anda dapat menggunakan pemeran ganda.

return (List<Customer>) (List) getList();

19
2017-12-18 18:18



Dengan Java 8 Streaming:

Terkadang pengecoran gaya kasar baik-baik saja:

List<MyClass> mythings = (List<MyClass>) (Object) objects

Tapi inilah solusi yang lebih fleksibel:

List<Object> objects = Arrays.asList("String1", "String2");

List<String> strings = list.stream()
                       .map(element->(String) element)
                       .collect(Collectors.toList());

Ada banyak sekali manfaat, tetapi salah satunya adalah Anda dapat mentransmisikan daftar Anda lebih elegan jika Anda tidak bisa memastikan apa yang dikandungnya:

list.stream()
    .filter(element->element instanceof String)
    .map(element->(String)element)
    .collect(Collectors.toList());

11
2017-07-19 19:27



Perhatikan bahwa saya bukan programmer java, tetapi dalam .NET dan C #, fitur ini disebut contravariance atau kovarian. Saya belum menyelidiki hal-hal tersebut, karena mereka masih baru. NET 4.0, yang tidak saya gunakan karena ini hanya beta, jadi saya tidak tahu yang mana dari kedua istilah tersebut yang menggambarkan masalah Anda, tetapi izinkan saya menggambarkan masalah teknis dengan ini.

Anggap saja Anda diizinkan untuk melakukan cast. Catatan, kataku melemparkan, karena itulah yang Anda katakan, tetapi ada dua operasi yang mungkin dilakukan, pengecoran dan mengkonversi.

Konversi berarti Anda mendapatkan objek daftar baru, tetapi Anda mengatakan casting, yang berarti Anda ingin memperlakukan sementara satu objek sebagai tipe lain.

Inilah masalahnya dengan itu.

Apa yang akan terjadi jika hal berikut diizinkan (perhatikan, saya berasumsi bahwa sebelum pemeran, daftar objek sebenarnya hanya berisi objek Pelanggan, jika tidak, pemain tidak akan berfungsi bahkan dalam versi hipotetis dari java ini):

List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];

Dalam hal ini, ini akan mencoba memperlakukan objek, yang bukan pelanggan, sebagai pelanggan, dan Anda akan mendapatkan kesalahan runtime pada satu titik, baik formulir di dalam daftar, atau dari tugas.

Generik, bagaimanapun, seharusnya memberi Anda tipe data yang aman-jenis, seperti koleksi, dan karena mereka suka melempar kata 'dijamin' di sekitar, jenis pemeran ini, dengan masalah yang mengikuti, tidak diperbolehkan.

Di. NET 4.0 (saya tahu, pertanyaan Anda adalah tentang java), ini akan diizinkan dalam beberapa kasus yang sangat spesifik, di mana kompilator dapat menjamin bahwa operasi yang Anda lakukan aman, tetapi dalam pengertian umum, jenis pemain ini tidak akan diizinkan. Hal yang sama berlaku untuk java, meskipun saya tidak yakin tentang rencana untuk memperkenalkan co dan kontravariance ke bahasa java.

Mudah-mudahan, seseorang dengan pengetahuan java yang lebih baik daripada saya dapat memberi tahu Anda spesifik untuk masa depan java atau implementasi.


8
2017-12-16 21:28



Anda hanya perlu melakukan iterasi pada daftar dan mentransmisikan semua Objek satu per satu


3
2017-12-16 21:27