Misalkan saya memiliki kelas dan metode
class A {
void foo() throws Exception() {
...
}
}
Sekarang saya ingin memanggil foo untuk setiap contoh yang A
dikirimkan oleh aliran seperti:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Pertanyaan: Bagaimana cara saya menangani pengecualian dengan benar? Kode tidak dikompilasi di mesin saya karena saya tidak menangani kemungkinan pengecualian yang dapat dilempar oleh foo (). The throws Exception
of bar
tampaknya tidak berguna di sini. Mengapa demikian?
java
java-8
unhandled-exception
java-stream
Bastian
sumber
sumber
Jawaban:
Anda harus memasukkan panggilan metode Anda ke panggilan lain, di mana Anda tidak membuang pengecualian yang dicentang . Anda masih dapat membuang apa pun yang merupakan subkelas dari
RuntimeException
.Idiom pembungkus yang normal adalah sesuatu seperti:
(Supertype pengecualian
Exception
yang hanya digunakan sebagai contoh, tidak pernah mencoba untuk menangkapnya sendiri)Kemudian Anda bisa menyebutnya dengan:
as.forEach(this::safeFoo)
.sumber
Jika semua yang Anda inginkan adalah memanggil
foo
, dan Anda lebih memilih untuk menyebarkan pengecualian seperti apa adanya (tanpa membungkus), Anda juga dapat menggunakanfor
loop Java saja (setelah mengubah Stream menjadi Iterable dengan beberapa tipu daya ):Ini, setidaknya, apa yang saya lakukan dalam tes JUnit saya, di mana saya tidak ingin melalui masalah membungkus pengecualian diperiksa (dan sebenarnya lebih suka tes saya untuk membuang yang asli yang terbuka)
sumber
Pertanyaan ini mungkin agak lama, tetapi karena saya pikir jawaban "benar" di sini hanya satu cara yang dapat menyebabkan beberapa masalah tersembunyi di kode Anda nanti. Bahkan jika ada sedikit Kontroversi , Pengecualian Diperiksa ada karena suatu alasan.
Cara paling elegan menurut saya dapat Anda temukan diberikan oleh Misha di sini Pengecualian runtime agregat di Java 8 stream dengan hanya melakukan tindakan dalam "masa depan". Jadi, Anda dapat menjalankan semua bagian yang bekerja dan mengumpulkan Pengecualian yang tidak berfungsi sebagai satu bagian. Kalau tidak, Anda bisa mengumpulkan semuanya dalam Daftar dan memprosesnya nanti.
Pendekatan serupa datang dari Benji Weber . Dia menyarankan untuk membuat tipe sendiri untuk mengumpulkan bagian yang bekerja dan tidak.
Bergantung pada apa yang Anda benar-benar ingin capai, pemetaan sederhana antara nilai input dan Nilai Output yang terjadi Pengecualian juga berlaku untuk Anda.
Jika Anda tidak menyukai cara-cara ini, pertimbangkan untuk menggunakan (tergantung pada Pengecualian Asli), setidaknya pengecualian sendiri.
sumber
stream.map(Streams.passException(x->mightThrowException(x))).catch(e->whatToDo(e)).collect(...)
. Itu sholud mengharapkan pengecualian dan memungkinkan Anda untuk menanganinya seperti masa depan.Saya sarankan untuk menggunakan kelas Google Guava Throwables
MEMPERBARUI:
Sekarang sudah tidak digunakan lagi:
sumber
Anda dapat membungkus dan membuka bukaan pengecualian dengan cara ini.
sumber
Anda mungkin ingin melakukan salah satu dari yang berikut:
Beberapa perpustakaan memungkinkan Anda melakukannya dengan mudah. Contoh di bawah ini ditulis menggunakan pustaka NoException saya .
sumber
Cara yang lebih mudah dibaca:
Cukup sembunyikan di
RuntimeException
untuk melewatinyaforEach()
Meskipun pada titik ini saya tidak akan menahan seseorang jika mereka mengatakan melewatkan aliran dan pergi dengan for for loop, kecuali:
Collection.stream()
, yaitu terjemahan tidak langsung ke for for loop.parallelstream()
sumber