Saya melihat POJO paling abadi ditulis seperti ini:
public class MyObject {
private final String foo;
private final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public String getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
Namun saya cenderung menulisnya seperti ini:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Perhatikan referensi bersifat final, sehingga Object tetap tidak berubah. Ini memungkinkan saya menulis lebih sedikit kode dan memungkinkan lebih pendek (dengan 5 karakter: get
dan ()
) akses.
Satu-satunya kelemahan yang bisa saya lihat adalah jika Anda ingin mengubah implementasi getFoo()
jalan untuk melakukan sesuatu yang gila, Anda tidak bisa. Tetapi secara realistis, ini tidak pernah terjadi karena Objek tidak dapat diubah; Anda dapat memverifikasi selama instantiasi, membuat salinan defensif yang tidak berubah selama instantiasi (lihat ImmutableList
contoh Guava ), dan menyiapkan foo
atau bar
objek untuk get
panggilan.
Apakah ada kerugian yang saya lewatkan?
SUNTING
Saya kira kerugian lain yang saya lewatkan adalah serialisasi perpustakaan menggunakan refleksi atas metode yang dimulai dengan get
atau is
, tapi itu praktik yang sangat mengerikan ...
sumber
final
tidak membuat variabel objek tidak berubah. Saya biasanya menggunakan desain di mana saya mendefinisikanfinal
bidang sebelum membuat panggilan balik sehingga panggilan balik dapat mengakses bidang itu. Itu bisa, tentu saja memanggil semua metode termasuksetX
metode apa pun .String
,int
atauMyObject
. Di versi pertama,final
hanya untuk memastikan bahwa metode selain konstruktor di dalam kelas tidak mencobabar = 7;
, misalnya. Dalam versi kedua,final
diperlukan untuk mencegah konsumen dari melakukan:MyObject x = new MyObject("hi", 5); x.bar = 7;
.Object
masih tetap. " Menyesatkan - dengan cara itu tampaknya Anda berpikir ada yangfinal Object
tidak berubah, padahal tidak. Maaf atas kesalahpahaman ini.myObj.getFoo().setFrob(...)
.Jawaban:
Empat kelemahan yang bisa saya pikirkan:
Yang mengatakan, versi Anda pasti lebih ringkas. Jika ini adalah kelas khusus yang hanya digunakan dalam paket tertentu (mungkin ruang lingkup paket adalah ide yang bagus di sini), maka saya dapat mempertimbangkan ini untuk sekali saja. Tapi saya tidak akan mengekspos API utama seperti ini.
sumber
Singkirkan getter / setter juga, dan Anda baik-baik saja!
Ini adalah topik yang sangat kontroversial di kalangan programmer Java.
Bagaimanapun, ada dua situtation di mana saya menggunakan variabel publik sebagai gantinya (!) Dari getter / setter:
sumber
Dalam kata-kata awam:
sumber
Salah satu kelemahan yang mungkin saya lihat begitu saja adalah Anda terikat pada representasi internal data di kelas. Ini mungkin bukan masalah besar, tetapi jika Anda menggunakan setter, dan Anda memutuskan bahwa foo dan bar akan dikembalikan dari beberapa kelas lain yang ditentukan di tempat lain, kelas yang mengkonsumsi MyObject tidak akan diminta untuk berubah. Anda hanya perlu menyentuh MyObject. Namun, jika Anda menggunakan nilai telanjang, maka Anda harus menyentuh di mana saja MyObject yang saya gunakan.
sumber