मैं इस तरह लिखे गए अधिकांश अपरिवर्तनीय POJOs देखता हूं:
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;
}
}
फिर भी मैं उन्हें इस तरह लिखना चाहता हूं:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
ध्यान दें कि संदर्भ अंतिम हैं, इसलिए ऑब्जेक्ट अभी भी अपरिवर्तनीय है। यह मुझे कम कोड लिखने देता है और कम (5 वर्णों द्वारा: get
और ()
) पहुंच की अनुमति देता है ।
एकमात्र नुकसान जो मैं देख सकता हूं, यदि आप getFoo()
कुछ पागल करने के लिए सड़क के कार्यान्वयन को बदलना चाहते हैं , तो आप नहीं कर सकते। लेकिन वास्तविक रूप से, ऐसा कभी नहीं होता है क्योंकि वस्तु अपरिवर्तनीय है; आप इन्स्टेन्शियशन दौरान सत्यापित कर सकते हैं, इन्स्टेन्शियशन दौरान अपरिवर्तनीय बचाव की मुद्रा में प्रतिलिपि बनाने (देखें अमरूद के ImmutableList
उदाहरण के लिए), और पाने foo
या bar
के लिए तैयार वस्तुओं get
कॉल।
क्या मुझे कोई कमी है?
संपादित करें
मुझे लगता है कि एक और नुकसान मुझे याद आ रहा है कि सीरियलाइज़ेशन लाइब्रेरियों के साथ शुरू होने वाले तरीकों पर प्रतिबिंब का उपयोग get
कर रहा है is
, लेकिन यह एक बहुत ही भयानक अभ्यास है ...
String
, int
या MyObject
। पहले संस्करण में, final
केवल यह सुनिश्चित करना है कि कक्षा के भीतर कंस्ट्रक्टर के अलावा अन्य तरीके bar = 7;
उदाहरण के लिए प्रयास न करें । दूसरे संस्करण में, final
उपभोक्ताओं को ऐसा करने से रोकने के लिए आवश्यक है MyObject x = new MyObject("hi", 5); x.bar = 7;
:।
Object
अभी भी अपरिवर्तनीय है। " भ्रामक है - इस तरह से यह प्रतीत होता है कि आपको लगता है कि कोई भी final Object
अपरिवर्तनीय है, जो यह नहीं है। गलतफहमी के लिए खेद है।
myObj.getFoo().setFrob(...)
।
final
एक चर वस्तु को अपरिवर्तनीय नहीं बनाता है। मैं आमतौर पर एक डिज़ाइन का उपयोग करता हूं जहां मैंfinal
कॉलबैक बनाने से पहले फ़ील्ड को परिभाषित करता हूं ताकि कॉलबैक उन फ़ील्ड तक पहुंच सके। यह निश्चित रूप से किसी भीsetX
तरीके सहित सभी तरीकों को कॉल कर सकता है ।