Di Jawa, mana yang lebih direkomendasikan, dan mengapa? Kedua jenis akan melempar pengecualian, sehingga dalam hal penanganannya adalah sama. assert
sedikit lebih pendek, tapi saya tidak yakin seberapa penting itu.
public void doStuff(Object obj) {
assert obj != null;
...
}
vs.
public void doStuff(Object obj) {
if (obj == null) {
throw new IllegalArgumentException("object was null");
}
...
}
java
exceptions
conventions
Daenyth
sumber
sumber
obj.hashCode()
;-)Jawaban:
WASPADALAH!
Pernyataan dihapus pada saat runtime kecuali Anda secara eksplisit menentukan untuk "mengaktifkan pernyataan" saat mengkompilasi kode Anda. Penegasan Java tidak boleh digunakan pada kode produksi dan harus dibatasi pada metode pribadi (lihat Pengecualian vs Penegasan ), karena metode pribadi diharapkan untuk diketahui dan digunakan hanya oleh pengembang. Juga
assert
akan melempar AssertionError yangError
tidak meluasException
, dan yang biasanya menunjukkan Anda memiliki kesalahan yang sangat tidak normal (seperti "OutOfMemoryError" yang sulit untuk dipulihkan, bukan?) Anda tidak diharapkan dapat mengobati.Hapus bendera "aktifkan pernyataan", dan periksa dengan debugger dan Anda akan melihat bahwa Anda tidak akan menginjak panggilan pemanggilan IllegalArgumentException ... karena kode ini belum dikompilasi (sekali lagi, ketika "ea" dihapus)
Lebih baik menggunakan konstruksi kedua untuk metode publik / dilindungi, dan jika Anda menginginkan sesuatu yang dilakukan dalam satu baris kode, setidaknya ada satu cara yang saya tahu. Saya pribadi menggunakan Spring Framework 's
Assert
kelas yang memiliki beberapa metode untuk memeriksa argumen dan melemparkan 'IllegalArgumentException' pada kegagalan. Pada dasarnya, yang Anda lakukan adalah:... Yang sebenarnya akan mengeksekusi kode yang persis sama dengan yang Anda tulis pada contoh kedua. Ada beberapa metode lain yang bermanfaat seperti
hasText
,hasLength
di sana.Saya tidak suka menulis lebih banyak kode daripada yang diperlukan, jadi saya senang ketika saya mengurangi jumlah baris yang ditulis sebanyak 2 (2 baris> 1 baris) :-)
sumber
java -ea
dan secara terprogram. @ Jalayn Saya pikir memiliki pernyataan dalam kode produksi sangat valid, karena mereka berguna untuk debugging di lapanganjava -ea
.Objects.requreNonNull
Anda perlu menggunakan pengecualian. Menggunakan pernyataan akan menjadi penyalahgunaan fitur.
Pengecualian yang tidak dicentang dirancang untuk mendeteksi kesalahan pemrograman pengguna perpustakaan Anda, sementara pernyataan dirancang untuk mendeteksi kesalahan dalam logika Anda sendiri . Ini adalah masalah terpisah yang tidak boleh dicampur.
Misalnya, sebuah pernyataan
berarti "Saya tahu bahwa setiap jalur kode yang mengarah ke pernyataan ini memastikan bahwa
myConnection
terhubung; jika kode di atas gagal mendapatkan koneksi yang valid, itu harusnya melemparkan pengecualian atau kembali sebelum mencapai titik ini."Di sisi lain, cek
berarti bahwa "Memanggil perpustakaan saya tanpa membuat sambungan adalah kesalahan pemrograman".
sumber
Jika Anda menulis fungsi yang tidak memungkinkan
null
sebagai nilai parameter yang valid, Anda harus menambahkan@Nonnull
anotasi ke tanda tangan dan gunakanObjects.requireNonNull
untuk memeriksa apakah argumennya adalahnull
dan melemparkan aNullPointerException
jika itu. The@Nonnull
penjelasan adalah untuk dokumentasi dan akan memberikan peringatan membantu pada waktu kompilasi dalam beberapa kasus. Itu tidak mencegahnull
dari diteruskan saat runtime.Memperbarui: The
@Nonnull
penjelasan bukan bagian dari Java perpustakaan standar. Sebagai gantinya, ada banyak standar yang bersaing dari perpustakaan pihak ketiga (lihat Anotasi @NotNull Java mana yang harus saya gunakan? ). Itu tidak berarti itu ide yang buruk untuk menggunakannya, hanya saja itu bukan standar.sumber
Objects.requireNonNull()
, yang baru bagi saya. Apakah Anda tahu jika ada metode "requireTrue ()" atau "requireEqual ()" yang serupa di mana saja? Tidak ada yang menentang Spring's Assert tetapi tidak semua orang menggunakannya.Objects.requireNonNull()
untuk validasi argumen. Jika suatu argumen diperlukan untuk menjaditrue
atau sama dengan sesuatu, maka argumen itu tidak ada gunanya. Untuk kasus kesalahan selain argumen ilegal, Anda harusthrow
seorangException
yang lebih akurat menggambarkan kesalahan. Ada juga JUnitAssert
tapi itu untuk tes.Objects.requireTrue(x >= 0.0);
,, atau untuk beberapa hash,Objects.requireEquals(hash.length == 256)
Saya selalu lebih suka melempar IllegalArgumentException daripada pernyataan.
Penegasan digunakan sebagian besar di JUnit atau alat pengujian lainnya, untuk memeriksa / menegaskan hasil pengujian. Jadi mungkin memberi kesan palsu kepada pengembang lain bahwa metode Anda adalah metode pengujian.
Juga masuk akal untuk melempar IllegalArgumentException ketika suatu metode telah melewati argumen ilegal atau tidak pantas . Ini lebih konsisten dengan konvensi Penanganan Pengecualian yang diikuti oleh pengembang Java.
sumber
IMO yang kedua sedikit lebih baik karena membawa lebih banyak informasi dan dapat diperpanjang (misalnya dengan memperluas kelas pengecualian) menjadi lebih informatif, juga tidak menggunakan perbandingan negatif yang lebih mudah dipahami.
sumber
Saya tidak banyak menggunakan aserts, tetapi pendekatan umum dengan Lombock @NonNull: https://projectlombok.org/features/NonNull
Implementasi Lombok: impor lombok.NonNull;
Versi Java:
Lombok adalah perpustakaan yang sangat bagus yang saya gunakan di mana-mana
sumber