मैं इस तरह लिखे गए अधिकांश अपरिवर्तनीय 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तरीके सहित सभी तरीकों को कॉल कर सकता है ।