perkenalan
NPE (NullpointerException) adalah pengecualian yang paling umum dalam program debugging. Google memiliki banyak diskusi tentang apakah metode tersebut harus mengembalikan nol atau baru objek kosong.
Di awal artikel, mari kita bicara tentang masalah NPE terlebih dahulu. Masalah NPE adalah NullpointerException yang sering kita temui dalam pengembangan. Misalkan kita memiliki dua kelas, dan diagram kelas UML mereka ditunjukkan pada gambar berikut
Dalam hal ini, ada kode berikut
user.getAddress (). getProvince ();
Cara menulis ini dapat melaporkan NullpointerException saat pengguna nol. Untuk menyelesaikan masalah ini, metode penulisan berikut diadopsi
if (user! = null) {alamat alamat = user.getAddress (); if (alamat! = null) {string province = address.getProvince (); }}Gaya penulisan ini relatif jelek. Untuk menghindari gaya penulisan jelek di atas, desain jelek menjadi elegan. JAVA8 menyediakan kelas opsional untuk mengoptimalkan metode penulisan ini, dan bagian teks berikut akan dijelaskan secara rinci.
PENDAHULUAN API
Biarkan saya pertama kali memperkenalkan API. Tidak seperti artikel lain, artikel ini mengadopsi metode analogi dan menggabungkan kode sumber. Tidak seperti artikel lain, setiap daftar API membuat orang tidak dapat menemukan poin kunci.
(1) Opsional (nilai t), kosong (), dari (nilai t), dari nilai yang dapat dibatalkan (nilai t)
Keempat fungsi ini memiliki korelasi, sehingga mereka ditempatkan dalam grup untuk memori.
Izinkan saya menjelaskan bahwa opsional (nilai t), yaitu konstruktor, adalah izin pribadi dan tidak dapat disebut secara eksternal. Tiga fungsi lainnya adalah izin publik untuk kami hubungi. Kemudian, esensi opsional adalah menyimpan nilai nyata secara internal, dan ketika membangun, ia secara langsung dinilai apakah nilainya kosong. Oke, itu masih cukup abstrak. Langsung unggah kode sumber konstruktor opsional (nilai t), seperti yang ditunjukkan pada gambar di bawah ini
Kemudian, kode sumber (nilai t) adalah sebagai berikut
public static <T> opsional <T> dari (nilai t) {return new opsional <> (nilai); } Dengan kata lain, konstruktor disebut secara internal oleh fungsi dari (nilai t). Berdasarkan kode sumber konstruktor, kita dapat menarik dua kesimpulan:
(1) Ketika nilai nilai kosong, nullpointerException masih akan dilaporkan.
(2) Objek opsional yang dibangun oleh fungsi (nilai t) dapat dibangun secara normal ketika nilai nilai tidak kosong.
Selain itu, kelas opsional juga mempertahankan objek dengan nilai nol, mungkin seperti berikut ini
Public Final Class Optional <T> {// oMit ...... Private Static Final Optional <?> Empty = New Optional <> (); private opsional () {this.value = null; } // empuk ... public static <T> Opsional <T> kosong () {@suppressWarnings ("Uncecked") Optional <T> t = (opsional <T>) kosong; mengembalikan t; }} Kemudian, fungsi kosong () adalah mengembalikan objek kosong.
Nah, begitu banyak persiapan telah diletakkan. Dapat dikatakan bahwa OfNablable (nilai T) memiliki fungsi, dan kode sumber ditambahkan.
public static <T> Opsional <T> OFNLUBLABLE (nilai t) {value return == NULL? kosong (): dari (nilai); } Yah, semua orang harus mengerti apa artinya. Perbedaan dibandingkan dengan (nilai t) adalah bahwa ketika nilai nilai adalah nol, dari (nilai t) akan melaporkan nullpointerException; Ofnullable (nilai t) tidak akan melempar pengecualian, dari nilai yang dapat dikembalikan (nilai t) secara langsung mengembalikan objek kosong.
Apakah itu berarti bahwa kita hanya menggunakan fungsi yang dapat dibatalkan alih -alih fungsi dalam proyek kita?
Tidak, jika ada sesuatu, maka secara alami akan memiliki nilai. Saat kami berlari, kami tidak ingin menyembunyikan NullpointerException. Sebaliknya, Anda perlu segera melaporkan, dan dalam hal ini, gunakan fungsi. Tetapi saya harus mengakui bahwa sebenarnya ada beberapa adegan seperti itu. Blogger hanya menggunakan fungsi ini dalam menulis kasus tes JUnit.
(2) orelse (t lainnya), orelseget (pemasok <? Memperluas t> lainnya) dan orelsethrow (pemasok <? Extends x> exceplionsupplier)
Ketiga fungsi ini dihafal dalam suatu kelompok, dan dipanggil ketika nilai yang dilewati oleh konstruktor adalah nol. Penggunaan orelse dan orelseget adalah sebagai berikut. Saat nilainya nol, nilai default diberikan:
@Testpublic void test () {user user = null; user = opsional.ofnullable (user) .orelse (createUser ()); user = opsional.ofnullable (user) .orelset (() -> createUser ()); } Public User CreateUser () {user user = new user (); user.setname ("Zhangsan"); mengembalikan pengguna;} Perbedaan antara kedua fungsi ini: Ketika nilai pengguna tidak nol, fungsi orelse masih akan menjalankan metode createUser (), sedangkan fungsi orelseget tidak akan menjalankan metode createUser (), sehingga Anda dapat mengujinya sendiri.
Sedangkan untuk orelsethrow, ketika nilainya nol, pengecualian dibuang secara langsung. Penggunaannya adalah sebagai berikut
Pengguna pengguna = null; opsional.ofnullable (pengguna) .orelsethrow (()-> pengecualian baru ("Pengguna tidak ada"));(3) peta (fungsi <? Super t ,? memperluas u> mapper) dan flatmap (fungsi <? Super t, opsional <u>> mapper)
Kedua fungsi ini ditempatkan dalam satu set memori, dan kedua fungsi ini melakukan pengoperasian nilai konversi.
Langsung Unggah Kode Sumber
Public Final Class Optional <T> {// oMit ...... public <u> opsional <u> peta (function <? Super t ,? Extends u> mapper) {objects.requirenonnull (mapper); if (! isPresent ()) kembali kosong (); else {return opsional.ofnullable (mapper.apply (value)); }} // empuk ... publik <u> opsional <u> flatmap (fungsi <? Super t, opsional <u>> mapper) {objeks.requirenonnull (mapper); if (! isPresent ()) kembali kosong (); else {return objects.requirenonnull (mapper.apply (value)); }}} Tidak ada perbedaan antara dua fungsi ini dalam tubuh fungsi. Satu -satunya perbedaan adalah parameter entri. Jenis parameter entri yang diterima oleh fungsi peta adalah fungsi <? Super T ,? memperpanjang u>, sedangkan tipe parameter entri flapmap adalah fungsi <? Super T, opsional <u>>.
Dalam hal penggunaan tertentu, untuk peta:
Jika struktur pengguna adalah sebagai berikut
pengguna kelas publik {nama string privat; public string getName () {return name; }}Saat ini, metode penulisan mengambil nama adalah sebagai berikut
String city = opsional.ofnullable (user) .map (u-> u.getname ()). Get ();
Untuk flatmap:
Jika struktur pengguna adalah sebagai berikut
pengguna kelas publik {nama string privat; Opsional publik <string> getName () {return opsional.ofnullable (name); }}Saat ini, metode penulisan mengambil nama adalah sebagai berikut
String city = opsional.ofnullable (user) .flatMap (u-> u.getname ()). Get ();
(4) isPresent () dan ifpresent (konsumen <? Super t> konsumen)
Satukan dua fungsi ini dan menghafalnya. ISPresent berarti untuk menentukan apakah nilainya kosong, dan jika tidak ada artinya melakukan beberapa operasi ketika nilainya tidak kosong. Kode sumber dari kedua fungsi ini adalah sebagai berikut
Public Final Class Optional <T> {// oMIT ...... public boolean isPresent () {value return! = null; } // hilangkan ... public void ifpresent (konsumen <? Super t> konsumen) {if (value! = Null) consumer.accept (value); }}Itu membutuhkan penjelasan tambahan, jangan
if (user! = null) {// todo: do something}Tertulis
Pengguna pengguna = opsional.ofnullable (pengguna); if (opsional.ispresent ()) {// todo: lakukan sesuatu} Karena itu, struktur kode masih jelek. Blogger akan memberikan metode penulisan yang benar nanti
Adapun ifpresent (konsumen <? Super t> konsumen), penggunaannya juga sangat sederhana, seperti yang ditunjukkan di bawah ini
Opsional.ofnullable (user) .ifpresent (u-> {// todo: do something});(5) filter (predikat <? Super t> prediktasi)
Tanpa basa -basi lagi, cukup unggah kode sumber
Public Final Class Optional <T> {// oMIT ...... objeks.requirenonnull (predikat); if (! isPresent ()) kembalikan ini; lain return preded preded.test (value)? ini: kosong ();} Metode filter menerima predikat untuk memfilter nilai yang terkandung dalam opsional. Jika nilai yang disertakan memenuhi syarat, maka opsional masih akan dikembalikan; Kalau tidak, Optional.empty akan dikembalikan.
Penggunaannya adalah sebagai berikut
Opsional <user> user1 = opsional.ofnullable (user) .filter (u -> u.getname (). Length () <6);
Seperti yang ditunjukkan di atas, jika panjang nama pengguna kurang dari 6, maka kembali. Jika lebih besar dari 6, objek kosong dikembalikan.
Penggunaan praktis
Contoh 1
Dalam metode fungsi
Tulisan sebelumnya
string publik getCity (pengguna pengguna) melempar pengecualian {if (user! = null) {if (user.getAddress ()! = null) {alamat alamat = user.getAddress (); if (address.getCity ()! = null) {return address.getCity (); }}} lempar expetion baru ("nilai kesalahan"); }Metode Penulisan Java8
Public String getCity (pengguna pengguna) melempar pengecualian {return opsional.ofnullable (user) .map (u-> u.getAddress ()) .map (a-> a.getCity ()) .orelsethrow (()-> Exception baru ("fetch error"));}Contoh 2
Misalnya, dalam program utama
Tulisan sebelumnya
if (user! = null) {dosomething (user);}Metode Penulisan Java8
Opsional.ofnullable (user) .ifpresent (u-> {dosomething (u);});Contoh 3
Tulisan sebelumnya
pengguna publik getUser (pengguna pengguna) melempar pengecualian {if (user! = null) {string name = user.getName (); if ("zhangsan" .Equals (name)) {return user; }} else {user = new user (); user.setname ("Zhangsan"); Pengguna Kembali; }}Metode Penulisan Java8
pengguna publik getUser (pengguna pengguna) {return opsional.ofnullable (user) .filter (u-> "zhangsan" .equals (u.getname ())) .orelset (()-> {user user1 = User baru (); user1.setname ("zhangsan"); kembalikan user1;});};};};};};Contoh lain tidak akan terdaftar satu per satu. Namun, blogger percaya bahwa menggunakan pemrograman rantai ini sebenarnya elegan dalam kode. Namun, logikanya tidak begitu jelas dan keterbacaan berkurang. Kami menggunakannya sesuai dengan situasi dalam proyek.
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.