polymorphism in java




गेटर्स और सेटर्स/एक्सेसर्स का उपयोग क्यों करें? (20)

गेटर्स और सेटर्स का उपयोग करने का क्या फायदा है - जो केवल उन चर के लिए सार्वजनिक फ़ील्ड का उपयोग करने के बजाय ही मिलता है और सेट करता है?

अगर गेटर्स और सेटर कभी भी सरल प्राप्त / सेट से अधिक कर रहे हैं, तो मैं इसे बहुत जल्दी से समझ सकता हूं, लेकिन मैं 100% स्पष्ट नहीं हूं कि कैसे:

public String foo;

इससे भी बदतर है:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

जबकि पूर्व बहुत कम बॉयलरप्लेट कोड लेता है।


हम गेटर्स और सेटर्स का उपयोग करते हैं:

  • पुन: प्रयोज्यता के लिए
  • प्रोग्रामिंग के बाद के चरणों में सत्यापन करने के लिए

निजी वर्ग के सदस्यों तक पहुंचने के लिए गेटटर और सेटर विधियां सार्वजनिक इंटरफेस हैं।

Encapsulation मंत्र

Encapsulation मंत्र फ़ील्ड निजी और विधियों सार्वजनिक बनाने के लिए है।

गेटर विधि: हम निजी चरों तक पहुंच प्राप्त कर सकते हैं।

सेटर तरीके: हम निजी क्षेत्रों को संशोधित कर सकते हैं।

भले ही गेटर और सेटर विधियां नई कार्यक्षमता नहीं जोड़ती हैं, फिर भी हम उस विधि को बनाने के लिए बाद में हमारे दिमाग को बदल सकते हैं

  • बेहतर;
  • सुरक्षित; तथा
  • और तेज।

कहीं भी एक मूल्य का उपयोग किया जा सकता है, एक विधि जो उस मान को वापस लाती है उसे जोड़ा जा सकता है। के बजाय:

int x = 1000 - 500

उपयोग

int x = 1000 - class_name.getValue();

आम आदमी के शब्दों में

मान लीजिए कि हमें इस Person के ब्योरे को स्टोर करने की जरूरत है। इस Person पास फ़ील्ड का name , age और sex । ऐसा करने में name , age और sex तरीकों का निर्माण करना शामिल है। अब अगर हमें किसी अन्य व्यक्ति को बनाने की ज़रूरत है, तो फिर से name , age , sex लिए विधियों को बनाना आवश्यक हो जाता है।

ऐसा करने के बजाय, हम गेटर और सेटर विधियों के साथ एक बीन class(Person) बना सकते हैं। तो कल जब भी हमें एक नया व्यक्ति जोड़ना होगा (आकृति देखें class(Person class) तो हम इस बीन class(Person class) की ऑब्जेक्ट्स बना सकते हैं। इस प्रकार हम बीन वर्ग के खेतों और विधियों का पुन: उपयोग कर रहे हैं, जो बहुत बेहतर है।


आपकी भाषा पर निर्भर करता है। आपने "जावा" के बजाए यह "ऑब्जेक्ट उन्मुख" टैग किया है, इसलिए मैं यह इंगित करना चाहता हूं कि ChssPly76 का उत्तर भाषा-निर्भर है। उदाहरण के लिए, पायथन में, गेटर्स और सेटर्स का उपयोग करने का कोई कारण नहीं है। यदि आपको व्यवहार को बदलने की ज़रूरत है, तो आप एक संपत्ति का उपयोग कर सकते हैं, जो मूल विशेषता पहुंच के आस-पास गेटर और सेटर को लपेटता है। कुछ इस तरह:

class Simple(object):
   def _get_value(self):
       return self._value -1

   def _set_value(self, new_value):
       self._value = new_value + 1

   def _del_value(self):
       self.old_values.append(self._value)
       del self._value

   value = property(_get_value, _set_value, _del_value)

एक शुद्ध वस्तु उन्मुख दुनिया में गेटर्स और सेटर्स एक भयानक विरोधी पैटर्न है । इस लेख को पढ़ें: गेटर्स / सेटर्स। बुराई। अवधि संक्षेप में, वे प्रोग्रामर को डेटा संरचनाओं के रूप में वस्तुओं के बारे में सोचने के लिए प्रोत्साहित करते हैं, और इस प्रकार की सोच शुद्ध प्रक्रियात्मक है (जैसे कोबोल या सी)। किसी ऑब्जेक्ट-ओरिएंटेड भाषा में कोई डेटा संरचना नहीं होती है, लेकिन केवल ऑब्जेक्ट्स जो व्यवहार का पर्दाफाश करती हैं (विशेषताएं / गुण नहीं!)

आप सुरुचिपूर्ण ऑब्जेक्ट्स (ऑब्जेक्ट उन्मुख प्रोग्रामिंग के बारे में मेरी पुस्तक) की धारा 3.5 में उनके बारे में अधिक जानकारी प्राप्त कर सकते हैं।


एक सार्वजनिक क्षेत्र गेटटर / सेटर जोड़ी से भी बदतर नहीं है जो फ़ील्ड लौटने और इसे असाइन करने के अलावा कुछ भी नहीं करता है। सबसे पहले, यह स्पष्ट है कि (ज्यादातर भाषाओं में) कोई कार्यात्मक अंतर नहीं है। किसी भी अंतर को अन्य कारकों में होना चाहिए, जैसे रखरखाव या पठनीयता।

गेटर / सेटर जोड़े का एक उल्लेखनीय लाभ नहीं है। यह दावा है कि आप कार्यान्वयन को बदल सकते हैं और आपके ग्राहकों को पुनः संयोजित करने की आवश्यकता नहीं है। माना जाता है कि, सेटर्स आपको बाद में सत्यापन जैसे कार्यक्षमता जोड़ने देते हैं और आपके क्लाइंट को इसके बारे में भी जानने की आवश्यकता नहीं है। हालांकि, एक सेटर को सत्यापन जोड़ना इसकी पूर्व शर्त में परिवर्तन है, पिछले अनुबंध का उल्लंघन , जो कि काफी सरल था, "आप यहां कुछ भी डाल सकते हैं, और आप बाद में प्राप्तकर्ता से वही चीज़ प्राप्त कर सकते हैं"।

तो, अब जब आप अनुबंध तोड़ चुके हैं, तो कोडबेस में प्रत्येक फ़ाइल को बदलना कुछ ऐसा है जो आपको करना चाहिए, इससे बचें नहीं। यदि आप इससे बचते हैं तो आप धारणा बना रहे हैं कि सभी कोड मानते हैं कि उन तरीकों के लिए अनुबंध अलग था।

अगर यह अनुबंध नहीं होना चाहिए था, तो इंटरफ़ेस ग्राहकों को ऑब्जेक्ट को अमान्य राज्यों में रखने की इजाजत दे रहा था। यह encapsulation के बिल्कुल विपरीत है अगर वह क्षेत्र वास्तव में शुरुआत से कुछ भी सेट नहीं किया जा सका, तो शुरुआत से सत्यापन क्यों नहीं था?

यह वही तर्क इन पास-थ्रू गेटर / सेटर जोड़े के अन्य अनुमानित फायदों पर लागू होता है: यदि आप बाद में सेट होने वाले मूल्य को बदलने का निर्णय लेते हैं, तो आप अनुबंध तोड़ रहे हैं। यदि आप व्युत्पन्न कक्षा में डिफ़ॉल्ट कार्यक्षमता को ओवरराइड करते हैं, तो कुछ हानिरहित संशोधनों (जैसे लॉगिंग या अन्य गैर-देखने योग्य व्यवहार) से परे, आप बेस क्लास के अनुबंध को तोड़ रहे हैं। यह लिस्कोव सबस्टिट्यूटिबिलिटी सिद्धांत का उल्लंघन है, जिसे ओओ के सिद्धांतों में से एक के रूप में देखा जाता है।

यदि किसी वर्ग में प्रत्येक क्षेत्र के लिए इन गूंगा गेटर्स और सेटर्स हैं, तो यह एक ऐसी कक्षा है जिसमें कोई भी आविष्कार नहीं है, कोई अनुबंध नहीं है । क्या वह वास्तव में ऑब्जेक्ट उन्मुख डिजाइन है? यदि सभी वर्गों में वे गेटर्स और सेटर्स हैं, तो यह सिर्फ एक गूंगा डेटा धारक है, और गूंगा डेटा धारकों को गूंगा डेटा धारकों की तरह दिखना चाहिए:

class Foo {
public:
    int DaysLeft;
    int ContestantNumber;
};

इस तरह के वर्ग में पास-थ्रू गेटर / सेटर जोड़े जोड़ना कोई मूल्य नहीं जोड़ता है। अन्य वर्गों को सार्थक संचालन प्रदान करना चाहिए, न केवल उन परिचालनों को जो पहले से ही प्रदान करते हैं। इस तरह आप उपयोगी आविष्कारों को परिभाषित और बनाए रख सकते हैं।

ग्राहक : "मैं इस वर्ग के किसी वस्तु के साथ क्या कर सकता हूं?"
डिजाइनर : "आप कई चर पढ़ और लिख सकते हैं।"
ग्राहक : "ओह ... अच्छा, मुझे लगता है?"

गेटर्स और सेटर्स का उपयोग करने के कारण हैं, लेकिन यदि उन कारणों का अस्तित्व नहीं है, तो झूठी encapsulation देवताओं के नाम पर गेटर / सेटर जोड़े बनाना एक अच्छी बात नहीं है। गेटर्स या सेटर्स बनाने के वैध कारणों में अक्सर उन संभावित परिवर्तनों के रूप में वर्णित चीजें शामिल होती हैं जिन्हें आप बाद में बना सकते हैं, जैसे सत्यापन या विभिन्न आंतरिक प्रतिनिधित्व। या शायद मूल्य ग्राहकों द्वारा पठनीय होना चाहिए लेकिन लिखने योग्य नहीं है (उदाहरण के लिए, एक शब्दकोश के आकार को पढ़ने), तो एक साधारण गेटर एक अच्छा विकल्प है। लेकिन जब आप पसंद करते हैं, तो न कि उन कारणों के साथ होना चाहिए, न कि एक संभावित चीज़ के रूप में जो आप बाद में चाहें। यह यज्ञी का एक उदाहरण है ( आपको इसकी आवश्यकता नहीं है )।


क्योंकि अब से 2 सप्ताह (महीने, साल) जब आप महसूस करते हैं कि आपके सेटर को केवल मूल्य निर्धारित करने से अधिक करने की आवश्यकता है, तो आपको यह भी पता चलेगा कि संपत्ति का उपयोग सीधे 238 अन्य वर्गों में किया गया है :-)


गेटर्स सेटर्स का उपयोग न करें जब तक कि आपके वर्तमान डिलीवरी के लिए जरूरी नहीं है Ie भविष्य में क्या होगा, इसके बारे में बहुत कुछ नहीं सोचें, अगर किसी भी चीज को इसे अधिकांश उत्पादन अनुप्रयोगों, सिस्टम में एक परिवर्तन अनुरोध बदलना है।

आवश्यकता होने पर सरल, आसान, जटिलता जोड़ें।

मैं गहरे तकनीकी के व्यापार मालिकों की अज्ञानता का लाभ नहीं उठाऊंगा, क्योंकि मुझे लगता है कि यह सही है या मुझे दृष्टिकोण पसंद है।

मेरे पास एक्सेस मॉडिफायर्स के साथ गेटर्स सेटर्स के बिना बड़े पैमाने पर सिस्टम लिखा गया है और एन निष्पादन बिज़ तर्क को सत्यापित करने के कुछ तरीके हैं। अगर आपको बिल्कुल जरूरत है। कुछ भी प्रयोग करें।


बहुत से लोग गेटर्स और सेटर्स के फायदों के बारे में बात करते हैं लेकिन मैं शैतान के वकील को खेलना चाहता हूं। अभी मैं एक बहुत बड़ा कार्यक्रम डीबग कर रहा हूं जहां प्रोग्रामर ने सब कुछ गेटर्स और सेटर्स बनाने का फैसला किया। यह अच्छा प्रतीत हो सकता है, लेकिन यह एक रिवर्स-इंजीनियरिंग दुःस्वप्न है।

मान लें कि आप सैकड़ों लाइन कोड देख रहे हैं और आप इस पर आते हैं:

person.name = "Joe";

जब तक आप इसे एक सेटटर महसूस नहीं करते हैं, यह कोड का एक सुंदर टुकड़ा है। अब, आप उस सेटर का अनुसरण करते हैं और पाते हैं कि यह व्यक्ति भी सेट करता है। पहला नाम, person.lastName, person.isHuman, person.hasReallyCommonFirstName, और person.update () को कॉल करता है, जो डेटाबेस को एक क्वेरी भेजता है आदि। ओह, यह है जहां आपकी मेमोरी रिसाव हो रही थी।

पहली नज़र में कोड के स्थानीय टुकड़े को समझना अच्छी पठनीयता की एक महत्वपूर्ण संपत्ति है जो गेटर्स और सेटर्स टूट जाते हैं। यही कारण है कि मैं उनसे बचने की कोशिश करता हूं जब मैं कर सकता हूं, और जब मैं उनका उपयोग करता हूं तो उन्हें कम करता है।


मुझे पता है कि यह थोड़ा देर हो चुकी है, लेकिन मुझे लगता है कि कुछ लोग हैं जो प्रदर्शन में रूचि रखते हैं :)

मैंने थोड़ा प्रदर्शन परीक्षण किया है। मैंने एक वर्ग "नंबरहोल्डर" लिखा जो अच्छी तरह से एक इंटीजर रखता है। आप या तो anInstance.getNumber() विधि anInstance.getNumber() का उपयोग करके या anInstance.number का उपयोग करके सीधे संख्या तक anInstance.getNumber() उस इंटीजर को पढ़ सकते हैं। मेरा प्रोग्राम दोनों तरीकों से 1,000,000,000 बार संख्या पढ़ता है। उस प्रक्रिया को पांच बार दोहराया जाता है और समय मुद्रित होता है। मुझे निम्नलिखित परिणाम मिल गया है:

Time 1: 953ms, Time 2: 741ms
Time 1: 655ms, Time 2: 743ms
Time 1: 656ms, Time 2: 634ms
Time 1: 637ms, Time 2: 629ms
Time 1: 633ms, Time 2: 625ms

(समय 1 सीधा तरीका है, टाइम 2 गेटटर है)

आप देखते हैं, गेटर (लगभग) हमेशा थोड़ा तेज है। तब मैंने विभिन्न चक्रों के साथ कोशिश की। 1 मिलियन के बजाय, मैंने 10 मिलियन और 0.1 मिलियन का उपयोग किया। परिणाम:

10 मिलियन चक्र:

Time 1: 6382ms, Time 2: 6351ms
Time 1: 6363ms, Time 2: 6351ms
Time 1: 6350ms, Time 2: 6363ms
Time 1: 6353ms, Time 2: 6357ms
Time 1: 6348ms, Time 2: 6354ms

10 मिलियन चक्र के साथ, समय लगभग समान हैं। यहां 100 हजार (0.1 मिलियन) चक्र हैं:

Time 1: 77ms, Time 2: 73ms
Time 1: 94ms, Time 2: 65ms
Time 1: 67ms, Time 2: 63ms
Time 1: 65ms, Time 2: 65ms
Time 1: 66ms, Time 2: 63ms

चक्रों की विभिन्न मात्रा के साथ, गेटटर नियमित तरीके से थोड़ा तेज है। मैं आशा करता हूं कि इससे आपको मदद मिली होगी! :)

वैसे, मैं अपने स्वयं के ज्ञान और Google Translator का उपयोग कर जर्मन सातवीं कक्षा हूं। तो मेरी अंग्रेजी के साथ इतना सख्त मत बनो;)


यह आलसी लोडिंग के लिए उपयोगी हो सकता है। कहें कि प्रश्न में ऑब्जेक्ट डेटाबेस में संग्रहीत है, और जब तक आपको इसकी आवश्यकता न हो, तब तक आप इसे प्राप्त नहीं करना चाहते हैं। यदि ऑब्जेक्ट को गेटटर द्वारा पुनर्प्राप्त किया जाता है, तो आंतरिक ऑब्जेक्ट शून्य हो सकता है जब तक कोई इसके लिए नहीं पूछता है, तो आप इसे गेटटर को पहली कॉल पर ले जा सकते हैं।

मेरे पास एक परियोजना में बेस पेज क्लास था जो मुझे सौंपा गया था जो कुछ अलग-अलग वेब सेवा कॉल से कुछ डेटा लोड कर रहा था, लेकिन उन वेब सेवा कॉलों में डेटा हमेशा सभी बच्चों के पृष्ठों में उपयोग नहीं किया जाता था। सभी लाभों के लिए वेब सेवाएं, "धीमी" की अग्रणी नई परिभाषाएं, इसलिए यदि आपको ऐसा करने की ज़रूरत नहीं है तो आप वेब सेवा कॉल नहीं करना चाहते हैं।

मैं सार्वजनिक क्षेत्रों से गेटर्स तक चले गए, और अब गेटर्स कैश की जांच करते हैं, और यदि यह नहीं है तो वहां वेब सेवा कॉल करें। तो थोड़ा लपेटने के साथ, बहुत सी वेब सेवा कॉल रोक दी गईं।

तो गेटटर मुझे पता लगाने की कोशिश से बचाता है, प्रत्येक बच्चे के पेज पर, मुझे क्या चाहिए। अगर मुझे इसकी ज़रूरत है, तो मैं गेटर को बुलाता हूं, और अगर यह मेरे पास पहले से नहीं है तो यह मेरे लिए खोज जाएगा।

    protected YourType _yourName = null;
    public YourType YourName{
      get
      {
        if (_yourName == null)
        {
          _yourName = new YourType();
          return _yourName;
        }
      }
    }

वैसे मैं सिर्फ यह जोड़ना चाहता हूं कि कभी-कभी वे आपके चर / ऑब्जेक्ट्स की समावेशन और सुरक्षा के लिए जरूरी हैं, अगर हम वास्तविक ऑब्जेक्ट ओरिएंटेड प्रोग्राम को कोड करना चाहते हैं, तो हमें एक्सेसर्स को ओवरस करना बंद करना होगा , कभी-कभी हम बहुत निर्भर करते हैं उन पर जब वास्तव में जरूरी नहीं है और यह लगभग समान होता है जैसे कि हम चर को सार्वजनिक करते हैं।


वास्तव में कक्षा के क्षेत्रों को उजागर करने के बजाय एक्सेसर्स का उपयोग करने पर विचार करने के कई अच्छे कारण हैं - केवल encapsulation के तर्क और भविष्य के परिवर्तनों को आसान बनाने से परे।

यहां कुछ कारण बताए गए हैं जिनके बारे में मुझे पता है:

  • संपत्ति को प्राप्त करने या सेट करने से जुड़े व्यवहार का समापन - इससे अतिरिक्त कार्यक्षमता (जैसे सत्यापन) को बाद में आसानी से जोड़ा जा सकता है।
  • एक वैकल्पिक प्रतिनिधित्व का उपयोग कर संपत्ति का खुलासा करते हुए संपत्ति के आंतरिक प्रतिनिधित्व को छुपाएं।
  • परिवर्तन से अपने सार्वजनिक इंटरफ़ेस को इन्सुलेट करना - मौजूदा इंटरफ़ेस को प्रभावित किए बिना कार्यान्वयन में परिवर्तन करते समय सार्वजनिक इंटरफ़ेस स्थिर रहना।
  • संपत्ति के जीवनकाल और स्मृति प्रबंधन (निपटान) अर्थशास्त्र को नियंत्रित करना - विशेष रूप से गैर-प्रबंधित स्मृति वातावरण (जैसे सी ++ या उद्देश्य-सी) में महत्वपूर्ण।
  • जब कोई संपत्ति रनटाइम पर बदलती है, तो डीबगिंग अवरोध बिंदु प्रदान करना - किसी विशेष मूल्य में कोई संपत्ति कब और कहां बदलती है, डीबगिंग कुछ भाषाओं में इसके बिना काफी मुश्किल हो सकती है।
  • पुस्तकालयों के साथ बेहतर इंटरऑपरेबिलिटी जो संपत्ति गेटटर / सेटर्स के खिलाफ संचालित करने के लिए डिज़ाइन की गई हैं - मॉकिंग, सीरियलाइजेशन और डब्ल्यूपीएफ दिमाग में आती हैं।
  • विरासतकर्ताओं को संपत्ति के व्यवहार के अर्थशास्त्र को बदलने के लिए अनुमति देना और गेटटर / सेटर विधियों को ओवरराइड करके उजागर किया जाता है।
  • गेटटर / सेटर को मूल्यों के बजाय लैम्ब्डा अभिव्यक्ति के रूप में पारित करने की अनुमति देना।
  • गेटर्स और सेटर्स विभिन्न एक्सेस स्तरों की अनुमति दे सकते हैं - उदाहरण के लिए, सार्वजनिक हो सकता है, लेकिन सेट को संरक्षित किया जा सकता है।

Additionally, this is to "future-proof" your class. In particular, changing from a field to a property is an ABI break, so if you do later decide that you need more logic than just "set/get the field", then you need to break ABI, which of course creates problems for anything else already compiled against your class.


EDIT: I answered this question because there are a bunch of people learning programming asking this, and most of the answers are very technically competent, but they're not as easy to understand if you're a newbie. We were all newbies, so I thought I'd try my hand at a more newbie friendly answer.

The two main ones are polymorphism, and validation. Even if it's just a stupid data structure.

Let's say we have this simple class:

public class Bottle {
  public int amountOfWaterMl;
  public int capacityMl;
}

A very simple class that holds how much liquid is in it, and what its capacity is (in milliliters).

What happens when I do:

Bottle bot = new Bottle();
bot.amountOfWaterMl = 1500;
bot.capacity = 1000;

Well, you wouldn't expect that to work, right? You want there to be some kind of sanity check. And worse, what if I never specified the maximum capacity? Oh dear, we have a problem.

But there's another problem too. What if bottles were just one type of container? What if we had several containers, all with capacities and amounts of liquid filled? If we could just make an interface, we could let the rest of our program accept that interface, and bottles, jerrycans and all sorts of stuff would just work interchangably. Wouldn't that be better? Since interfaces demand methods, this is also a good thing.

We'd end up with something like:

public interface LiquidContainer {
  public int getAmountMl();
  public void setAmountMl(int amountMl);
  public int getCapacityMl();
  public void setCapcityMl(int capacityMl);
}

महान! And now we just change Bottle to this:

public class Bottle extends LiquidContainer {
  private int capacityMl;
  private int amountFilledMl;
  public Bottle(int capacityMl, int amountFilledMl) {
    this.capacityMl = capacityMl;
    this.amountFilledMl = amountFilledMl;
    checkNotOverFlow();
  }

  public int getAmountMl() {
    return amountFilledMl;
  }

  public void setAmountMl(int amountMl) {
     this.amountFilled = amountMl;
     checkNotOverFlow();
  }
  public int getCapacityMl() {
    return capacityMl;
  public void setCapcityMl(int capacityMl) {
    this.capacityMl = capacityMl;
    checkNotOverFlow();
  }

  private void checkNotOverFlow() {
    if(amountOfWaterMl > capacityMl) {
      throw new BottleOverflowException();
    }
}

I'll leave the definition ofthe BottleOverflowException as an exercise to the reader.

Now notice how much more robust this is. We can deal with any type of container in our code now by accepting LiquidContainer instead of Bottle. And how these bottles deal with this sort of stuff can all differ. You can have bottles that writer their state to disk when it changes, or bottles that save on SQL databases or GNU knows what else.

And all these can have different ways to handle various whoopsies. The Bottle just checks and if it's overflowing it throws a RuntimeException. But that might be the wrong thing to do. (There is a useful discussion to be had about error handling, but I'm keeping it very simple here on purpose. People in comments will likely point out the flaws of this simplistic approach. ;) )

And yes, it seems like we go from a very simple idea to getting much better answers quickly.

There's also the third thing that not everyone has addressed: Getters and setters use method calls. That means that they look like normal methods everywhere else does. Instead of having weird specific syntax for DTOs and stuff, you have the same thing everywhere.


From a object orientation design standpoint both alternatives can be damaging to the maintenance of the code by weakening the encapsulation of the classes. For a discussion you can look into this excellent article: http://typicalprogrammer.com/?p=23


I can think of one reason why you wouldn't just want everything public.

For instance, variable you never intended to use outside of the class could be accessed, even irdirectly via chain variable access (ie object.item.origin.x ).

By having mostly everything private, and only the stuff you want to extend and possibly refer to in subclasses as protected, and generally only having static final objects as public, then you can control what other programmers and programs can use in the API and what it can access and what it can't by using setters and getters to access the stuff you want the program, or indeed possibly other programmers who just happen to use your code, can modify in your program.


I would just like to throw the idea of annotation : @getter and @setter. With @getter, you should be able to obj = class.field but not class.field = obj. With @setter, vice versa. With @getter and @setter you should be able to do both. This would preserve encapsulation and reduce the time by not calling trivial methods at runtime.


One aspect I missed in the answers so far, the access specification:

  • for members you have only one access specification for both setting and getting
  • for setters and getters you can fine tune it and define it separately

One of the basic principals of OO design: Encapsulation!

It gives you many benefits, one of which being that you can change the implementation of the getter/setter behind the scenes but any consumer of that value will continue to work as long as the data type remains the same.


One relatively modern advantage of getters/setters is that is makes it easier to browse code in tagged (indexed) code editors. Eg If you want to see who sets a member, you can open the call hierarchy of the setter.

On the other hand, if the member is public, the tools don't make it possible to filter read/write access to the member. So you have to trudge though all uses of the member.


There is a good reason to consider using accessors is there is no property inheritance. See next example:

public class TestPropertyOverride {
    public static class A {
        public int i = 0;

        public void add() {
            i++;
        }

        public int getI() {
            return i;
        }
    }

    public static class B extends A {
        public int i = 2;

        @Override
        public void add() {
            i = i + 2;
        }

        @Override
        public int getI() {
            return i;
        }
    }

    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.i);
        a.add();
        System.out.println(a.i);
        System.out.println(a.getI());
    }
}

आउटपुट:

0
0
4




abstraction