Bu şekilde yazılmış çoğu değişmez POJO'yu görüyorum:
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;
}
}
Yine de onları bu şekilde yazmaya meyilliyim:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Referansların nihai olduğuna dikkat edin, bu nedenle Nesne hala değişmez. Daha az kod yazmama izin veriyor ve daha kısa (5 karakter: get
ve ()
) erişimine izin veriyor .
Görebildiğim tek dezavantaj getFoo()
, çılgınca bir şey yapmak için yolun aşağısındaki uygulamasını değiştirmek isteyip istemediğinizdir . Fakat gerçekçi olarak, bu asla gerçekleşmez, çünkü Nesne değişmezdir; örnekleme sırasında doğrulayabilir, örnekleme sırasında değişmez savunma kopyaları oluşturabilir ( ImmutableList
örneğin Guava'nın bakınız ) ve foo
veya bar
nesneye get
çağrı için hazır olun .
Kaybettiğim herhangi bir dezavantaj var mı?
DÜZENLE
Sanırım eksik olduğum başka bir dezavantaj ise get
veya ile başlayan yöntemlere yansıma kullanan serileştirme kütüphaneleri is
, ama bu oldukça korkunç bir uygulama ...
String
, int
ya MyObject
. İlk versiyonda, final
sadece sınıf içindeki yapıcıdan başka yöntemlerin denenmemesini sağlamaktır bar = 7;
. İkinci versiyonda, final
yapmaktan tüketicilerin önlemek için gereklidir: MyObject x = new MyObject("hi", 5); x.bar = 7;
.
Object
hala değişken değil. " Yanıltıcıdır - öyle görünüyor ki herhangi final Object
birinin değişmez olduğunu düşünüyorsunuz , ki bu değil. Yanlış anlaşılma için üzgünüm.
myObj.getFoo().setFrob(...)
.
final
değişkeni nesneyi değişmez yapmaz. Normaldefinal
geri arama oluşturmadan önce alanları tanımladığım bir tasarım kullanıyorum, böylece geri arama bu alanlara erişebiliyor. Elbette, herhangi birsetX
yöntem dahil tüm yöntemleri çağırabilir .