जावा 8 इंटरफ़ेस विधियों में "अंतिम" की अनुमति क्यों नहीं है?


335

जावा 8 की सबसे उपयोगी विशेषताओं में से एक defaultइंटरफेस पर नए तरीके हैं। अनिवार्य रूप से दो कारण हैं (वहाँ अन्य भी हो सकते हैं) उन्हें क्यों पेश किया गया है:

  • वास्तविक डिफ़ॉल्ट कार्यान्वयन प्रदान करना। उदाहरण:Iterator.remove()
  • जेडीके एपीआई विकास के लिए अनुमति। उदाहरण:Iterable.forEach()

एपीआई डिज़ाइनर के दृष्टिकोण से, मैं इंटरफ़ेस विधियों पर अन्य संशोधक का उपयोग करने में सक्षम होना पसंद करता हूं, जैसे final। यह उपयोगी होगा जब सुविधा के तरीकों को जोड़ते हुए, कक्षाओं को लागू करने में "आकस्मिक" को रोका जा सके:

interface Sender {

    // Convenience method to send an empty message
    default final void send() {
        send(null);
    }

    // Implementations should only implement this method
    void send(String message);
}

ऊपर पहले से ही सामान्य अभ्यास है अगर Senderएक वर्ग थे:

abstract class Sender {

    // Convenience method to send an empty message
    final void send() {
        send(null);
    }

    // Implementations should only implement this method
    abstract void send(String message);
}

अब, defaultऔर finalस्पष्ट रूप से कीवर्ड का खंडन कर रहे हैं, लेकिन डिफ़ॉल्ट कीवर्ड खुद ही कड़ाई से आवश्यक नहीं होगा , इसलिए मैं मान रहा हूं कि यह विरोधाभास जानबूझकर है, "शरीर के साथ वर्ग विधियों" (सिर्फ तरीकों) और "इंटरफ़ेस" के बीच सूक्ष्म अंतर को प्रतिबिंबित करने के लिए शरीर के साथ तरीके " (डिफ़ॉल्ट तरीके), यानी मतभेद जो मुझे अभी तक समझ नहीं आए हैं।

कुछ समय में, ब्रायन गोएट्ज का हवाला देते हुए , जैसे इंटरफ़ेस पर staticऔर finalइंटरफ़ेस के तरीकों के लिए समर्थन अभी तक पूरी तरह से पता नहीं लगाया गया था :

दूसरा हिस्सा है कि हम इंटरफेस में क्लास-बिल्डिंग टूल्स का समर्थन करने जा रहे हैं, जैसे कि अंतिम तरीके, निजी तरीके, संरक्षित तरीके, स्थिर तरीके, आदि। इसका जवाब है: हम अभी तक नहीं जानते हैं

2011 के अंत में उस समय से, जाहिर है, staticइंटरफेस में तरीकों के लिए समर्थन जोड़ा गया था। जाहिर है, इसने JDK पुस्तकालयों के लिए बहुत सारे मूल्य जोड़े, जैसे कि Comparator.comparing()

सवाल:

क्या कारण है final(और यह भी static final) इसे जावा 8 इंटरफेस के लिए कभी नहीं बनाया?


10
मुझे गीले कंबल के लिए खेद है, लेकिन शीर्षक में व्यक्त एकमात्र तरीका एसओ की शर्तों के भीतर उत्तर देने वाला है, ब्रायन गोएत्ज़ या जेएसआर विशेषज्ञ समूह के एक उद्धरण के माध्यम से है। मैं समझता हूं कि बीजी ने सार्वजनिक चर्चा का अनुरोध किया है, लेकिन यह वास्तव में एसओ की शर्तों का उल्लंघन करता है, क्योंकि यह 'मुख्य रूप से राय-आधारित' है। मुझे लगता है कि यहां जिम्मेदारियों को धराशायी किया जा रहा है। यह विशेषज्ञ समूह का काम है, और व्यापक जावा समुदाय प्रक्रिया है, चर्चा को प्रोत्साहित करने और तर्कसंगतता के साथ आने के लिए। एसओ का नहीं। इसलिए मैं 'मुख्य रूप से राय-आधारित' के रूप में बंद होने के लिए मतदान कर रहा हूं।
लोर्ने का मार्किस

2
जैसा कि हम सभी जानते हैं, finalएक विधि को ओवरराइड होने से रोकता है, और यह देखते हुए कि आप इंटरफेस से विरासत में मिली विधियों को कैसे ओवरराइड करते हैं, मैं नहीं देखता कि इसे अंतिम बनाने के लिए यह समझ में क्यों आता है। जब तक यह संकेत नहीं देना था कि यह विधि एक बार इसे ओवरराइड करने के बाद अंतिम है .. उस स्थिति में, शायद qas कठिनाइयाँ हैं? अगर मैं इस अधिकार को नहीं समझ रहा हूं, तो कृपया मुझे kmow दें। दिलचस्प लगता है
विंस एमघे

22
@ ईजेपी: "अगर मैं ऐसा कर सकता हूं, तो आप कर सकते हैं, और अपने खुद के सवाल का जवाब दे सकते हैं, इसलिए यह पूछने की जरूरत नहीं होगी।" यह इस मंच पर बहुत सारे सवालों पर लागू होता है, है ना? मैं हमेशा 5 घंटे के लिए Google को कुछ विषय दे सकता था और फिर कुछ ऐसा सीख सकता हूं जो बाकी सभी को समान रूप से कठिन तरीके से सीखना पड़े। या हम किसी और बेहतर जवाब देने के लिए किसी और जोड़े के लिए कुछ मिनटों तक प्रतीक्षा करते हैं, ताकि भविष्य में हर कोई (12 अपवोट और अब तक के 8 सितारों सहित) से लाभ उठा सके, क्योंकि एसओ गूगल पर बहुत अच्छी तरह से संदर्भित है। तो हाँ। यह सवाल कर सकते हैं पूरी तरह से तो चलो क्यू एंड ए प्रपत्र में फिट।
लुकास ईडर

5
@VinceEmigh " ... यह देखकर कि आप इंटरफेस से विरासत में मिली विधियों को कैसे ओवरराइड करते हैं ... " यह जावा 8 में सच नहीं है। जावा 8 आपको इंटरफेस में तरीकों को लागू करने की अनुमति देता है, जिसका अर्थ है कि आपको उन्हें लागू करने की आवश्यकता नहीं है। कक्षाएं। यहाँ, finalएक इंटरफ़ेस विधि के डिफ़ॉल्ट कार्यान्वयन को ओवरराइड करने से कक्षाएं लागू करने से रोकने में इसका उपयोग होगा।
awksp

28
@EJP आप कभी नहीं जानते: ब्रायन Goetz जवाब दे सकते हैं !
assylias

जवाबों:


419

यह प्रश्न, कुछ हद तक, संबंधित है कि जावा 8 इंटरफ़ेस विधियों में "सिंक्रोनाइज़" करने की क्या वजह है?

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

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

"अंतिम फ़ाइनल मेथड्स क्यों नहीं" का बहुत सरल उत्तर यह है कि तब बॉडी केवल डिफॉल्ट इम्प्लीमेंटेशन नहीं होगी, यह केवल इम्प्लीमेंटेशन होगा। जबकि यह एक छोटा सा जवाब है, यह हमें एक सुराग देता है कि सवाल पहले से ही एक संदिग्ध दिशा में बढ़ रहा है।

अंतिम इंटरफ़ेस विधियों के संदिग्ध होने का एक और कारण यह है कि वे कार्यान्वयनकर्ताओं के लिए असंभव समस्याएं पैदा करते हैं। उदाहरण के लिए, मान लीजिए कि आपके पास:

interface A { 
    default void foo() { ... }
}

interface B { 
}

class C implements A, B { 
}

यहाँ, सब कुछ अच्छा है; Cसे विरासत में मिला foo()है A। अब मान लिया Bगया है कि fooडिफ़ॉल्ट के साथ एक विधि है:

interface B { 
    default void foo() { ... }
}

अब, जब हम recompile पर जाते हैं C, तो कंपाइलर हमें बताएगा कि उसे यह नहीं पता है कि किस व्यवहार के लिए विरासत में मिला है foo(), इसलिए Cइसे ओवरराइड करना होगा (और A.super.foo()यदि वह उसी व्यवहार को बनाए रखना चाहता था तो प्रतिनिधि को चुन सकता है।) लेकिन क्या अगर। Bने अपना डिफ़ॉल्ट बनाया है final, और Aलेखक के नियंत्रण में नहीं है C? अब Cगैर-कानूनी रूप से टूट गया है; यह ओवरराइडिंग के बिना संकलित नहीं कर सकता है foo(), लेकिन foo()अगर यह अंतिम था तो इसे ओवरराइड नहीं कर सकता B

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

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


88
नई भाषा सुविधाओं के बारे में सवालों के जवाब देने के लिए आपको शानदार! यह बहुत उपयोगी हो रहा है कि डिजाइन के इरादे और विवरण के बारे में स्पष्टीकरण प्राप्त करने के लिए कि हम नई सुविधाओं का उपयोग कैसे करें । क्या अन्य लोग जो एसओ में योगदान देने वाले डिजाइन के साथ शामिल थे - या आप बस खुद ऐसा कर रहे हैं? मैं java-8 टैग के तहत आपके उत्तरों का पालन करूंगा - मैं जानना चाहता हूं कि क्या अन्य लोग भी ऐसा ही कर रहे हैं तो मैं भी उनका अनुसरण कर सकता हूं।
छीना हुआ

10
@ शोर्न स्टुअर्ट मार्क्स जावा -8 टैग में सक्रिय रहे हैं। जेरेमी मैनसन ने अतीत में पोस्ट किया है। मुझे यह भी याद है कि यहोशू बलोच के संदेश देख रहे हैं, लेकिन अभी उन्हें नहीं पा सकते हैं।
अस्वच्छता ass

1
डिफ़ॉल्ट इंटरफ़ेस विधियों के साथ आने के लिए बधाई देने का एक और अधिक सुरुचिपूर्ण तरीका है, जो C # अपने दुर्भावनापूर्ण और बदसूरत कार्यान्वित विस्तार विधियों के साथ करता है। इस सवाल के लिए, नाम संघर्ष के प्रकार को हल करने की असंभवता के बारे में जवाब इस मुद्दे को सुलझाता है, लेकिन प्रदान किए गए बाकी कारण असंबद्ध दार्शनिक थे। (अगर मैं एक इंटरफ़ेस विधि को अंतिम रूप देना चाहता हूं, तो आपको यह मान लेना चाहिए कि मेरे पास किसी से भी किसी भी कार्यान्वयन को प्रदान करने से रोकने के लिए मेरे अपने बहुत अच्छे कारण हैं।)
माइक नाकिस

1
फिर भी, नाम संघर्ष समाधान को एक समान तरीके से प्राप्त किया जा सकता है कि यह C # में कैसे किया जाता है, कार्यान्वयन विधि की घोषणा के लिए लागू किए जा रहे विशेष इंटरफ़ेस का नाम जोड़कर। इसलिए, मैं इस सब से घर लेती हूं कि डिफ़ॉल्ट इंटरफ़ेस विधियां जावा में अंतिम नहीं हो सकती हैं, क्योंकि इसके लिए सिंटैक्स में अतिरिक्त संशोधनों की आवश्यकता होगी, जिसके बारे में आपको अच्छा नहीं लगा। (बहुत सी-शार्पिश शायद?)
माइक नाकिस

18
@ ट्रेसिंग सार कक्षाएं अभी भी राज्य को शुरू करने, या कोर ऑब्जेक्ट विधियों को लागू करने का एकमात्र तरीका है। डिफ़ॉल्ट तरीके शुद्ध व्यवहार के लिए हैं ; सार कक्षाएं राज्य के साथ युग्मित व्यवहार के लिए हैं।
ब्रायन गोएट्ज

43

लैंबडा मेलिंग लिस्ट में इसे लेकर काफी चर्चाएं हैं । उन सभी में से एक के बारे में बहुत चर्चा होती है, जो निम्न है: सामान पर इंटरफ़ेस विधि दृश्यता (अंतिम रक्षक थी)

इस चर्चा में, मूल प्रश्न के लेखक, टल्डेन, आपके प्रश्न के समान ही कुछ पूछते हैं:

सभी इंटरफ़ेस सदस्यों को सार्वजनिक करने का निर्णय वास्तव में एक दुर्भाग्यपूर्ण निर्णय था। कि आंतरिक डिजाइन में इंटरफ़ेस का कोई भी उपयोग कार्यान्वयन को उजागर करता है निजी विवरण एक बड़ा है।

भाषा के लिए कुछ अस्पष्ट या अनुकूलता को तोड़ने वाली बारीकियों को जोड़े बिना इसे ठीक करना एक कठिन है। उस परिमाण और संभावित सूक्ष्मता के अनुकूलता विच्छेद को असंगत देखा जाएगा ताकि एक समाधान मौजूद हो जो मौजूदा कोड को नहीं तोड़ता है।

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

डिफ़ॉल्ट विधियों की अनुपस्थिति में, मैंने अनुमान लगाया था कि किसी इंटरफ़ेस में किसी सदस्य की निर्दिष्ट संख्या कम से कम इंटरफ़ेस के रूप में दिखाई दे सकती है (इसलिए इंटरफ़ेस वास्तव में सभी दृश्य संदर्भों में लागू किया जा सकता है) - डिफ़ॉल्ट विधियों के साथ नहीं इतना निश्चित है।

क्या इसका कोई स्पष्ट संचार है कि क्या यह एक संभव गुंजाइश चर्चा है? यदि नहीं, तो इसे कहीं और आयोजित किया जाना चाहिए।

आखिरकार ब्रायन गोएत्ज़ का जवाब था:

हां, यह पहले से ही पता लगाया जा रहा है।

हालाँकि, मुझे कुछ यथार्थवादी अपेक्षाएँ निर्धारित करने दें - भाषा / वीएम विशेषताओं का एक लंबा लीड समय होता है, यहां तक ​​कि तुच्छ-प्रतीत होने वाले भी। जावा एसई 8 के लिए नई भाषा के विचारों को प्रस्तावित करने का समय बहुत अधिक बीत चुका है।

इसलिए, सबसे अधिक संभावना है कि इसे कभी लागू नहीं किया गया था क्योंकि यह कभी भी गुंजाइश का हिस्सा नहीं था। इस पर विचार किया जाना समय में प्रस्तावित नहीं था।

विषय पर अंतिम डिफेंडर विधियों के बारे में एक और गर्म चर्चा में , ब्रायन ने फिर से कहा :

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

इसलिए यह मेरे सिद्धांत को पुष्ट करता है कि यह केवल उनके डिजाइन के दायरे या भाग का हिस्सा नहीं था। एपीआई विकास के मुद्दों से निपटने के लिए उन्होंने पर्याप्त कार्यक्षमता प्रदान करने के लिए क्या किया।


4
मैं देख रहा हूं कि मुझे आज सुबह अपने गुगली ओडिसी में पुराने नाम, "डिफेंडर के तरीकों" को शामिल करना चाहिए था। इसे खोदने के लिए +1।
मार्को 13

1
ऐतिहासिक तथ्यों की अच्छी खुदाई। आपके निष्कर्ष आधिकारिक उत्तर के
लुकास ईडर

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

17

यह खोजने के लिए और पहचान "" जवाब है, resons @EJP से टिप्पणी में उल्लेख किया है के लिए के लिए मुश्किल हो जाएगा: वहाँ लगभग 2 (+/- 2) दुनिया में लोग हैं, जो निश्चित जवाब दे सकते हैं सब पर । और संदेह में, जवाब कुछ ऐसा हो सकता है जैसे "अंतिम डिफ़ॉल्ट तरीकों का समर्थन करना आंतरिक कॉल रिज़ॉल्यूशन तंत्र के पुनर्गठन के प्रयास के लायक नहीं लगता"। यह अटकलबाजी है, लेकिन यह कम से कम सूक्ष्म साक्ष्य द्वारा समर्थित है, जैसे कि OpenJDK मेलिंग सूची में इस कथन (दो व्यक्तियों में से एक) द्वारा :

"मुझे लगता है कि अगर" अंतिम डिफ़ॉल्ट "विधियों की अनुमति थी, तो उन्हें आंतरिक इनवोकस्पेक्टर से उपयोगकर्ता-दृश्य प्रोक्योरफेस की पुनर्लेखन की आवश्यकता हो सकती है।"

और तुच्छ तथ्य जैसे कि एक विधि को केवल एक (वास्तव में) अंतिम विधि नहीं माना जाता है जब यह एक defaultविधि है, जैसा कि वर्तमान में OpenJDK में विधि :: is_final_method पद्धति में लागू किया गया है ।

इसके अलावा वास्तव में "आधिकारिक" जानकारी वास्तव में खोजने के लिए कठिन है, यहां तक ​​कि अत्यधिक वेबसर्च के साथ और कमिट लॉग पढ़ने से भी। मैंने सोचा था कि यह invokeinterfaceनिर्देश के साथ इंटरफ़ेस विधि कॉल के समाधान के दौरान संभावित अस्पष्टताओं से संबंधित हो सकता है , और निर्देश के अनुसार वर्ग विधि कॉल, invokevirtualनिर्देश के लिए: invokevirtualनिर्देश के लिए, एक सरल व्यवहार्य खोज हो सकती है , क्योंकि विधि या तो विरासत में मिली होगी एक सुपरक्लास से, या सीधे वर्ग द्वारा लागू किया गया। इसके विपरीत, एक invokeinterfaceकॉल को संबंधित कॉल साइट की जांच करनी चाहिए ताकि यह पता चल सके कि यह कॉल वास्तव में किस इंटरफ़ेस को संदर्भित करता है (इसे हॉटस्पॉट विकी के इंटरफ़ेसकॉल पृष्ठ में अधिक विस्तार से समझाया गया है )। तथापि,final तरीकों है या तो सम्मिलित नहीं करें vtable सब पर, या में वर्तमान जानकारी को बदलें vtable (देखें klassVtable.cpp। रेखा 333 ), और इसी प्रकार, डिफ़ॉल्ट तरीकों में वर्तमान जानकारी को प्रतिस्थापित करती हैं vtable (देखें klassVtable.cpp, रेखा 202 ) । तो वास्तविक कारण (और इस प्रकार, उत्तर) को गहराई से (बल्कि जटिल) विधि कॉल रिज़ॉल्यूशन तंत्र के अंदर छिपाया जाना चाहिए, लेकिन हो सकता है कि इन संदर्भों को फिर भी सहायक माना जाएगा, यह केवल दूसरों के लिए है जो वास्तविक उत्तर प्राप्त करने का प्रबंधन करते हैं। उसमें से।


दिलचस्प अंतर्दृष्टि के लिए धन्यवाद। जॉन रोज द्वारा दिया गया टुकड़ा एक दिलचस्प ट्रेस है। मैं अभी भी @EJP से सहमत नहीं हूँ, हालाँकि। एक काउंटर-उदाहरण के रूप में, पीटर लॉरी द्वारा एक बहुत ही दिलचस्प, बहुत ही समान शैली के सवाल के मेरे जवाब की जांच करें । यह है ऐतिहासिक तथ्यों को खुदाई करने के लिए संभव है, और मैं हमेशा यहाँ स्टैक ओवरफ़्लो पर उन्हें खोजने के लिए खुश हूँ (और कहाँ?)। बेशक, आपका जवाब अभी भी अटकलें हैं, और मैं 100% आश्वस्त नहीं हूं कि जेएलएम कार्यान्वयन विवरण जेएलएस के लिए एक या दूसरे तरीके से लिखे जाने का अंतिम कारण (दंड का उद्देश्य) होगा ...
लुकास एडर

@LukasEder ज़रूर, इस प्रकार के प्रश्न दिलचस्प और IMHO प्रश्नोत्तर पैटर्न में फिट होते हैं । मुझे लगता है कि दो महत्वपूर्ण बिंदु हैं जो यहां विवाद का कारण बने: पहला यह है कि आपने "कारण" पूछा। यह कई मामलों में सिर्फ आधिकारिक तौर पर प्रलेखित नहीं किया जा सकता है। उदाहरण के लिए JLS में कोई "कारण" नहीं बताया गया है कि कोई अहस्ताक्षरित क्यों नहीं हैं int, फिर भी देखें stackoverflow.com/questions/430346 ... ...
Marco13

... ... दूसरा यह है कि आपने केवल "आधिकारिक उद्धरण" के लिए कहा है , जो उन लोगों की संख्या को कम करता है जो "कुछ दर्जन" से उत्तर लिखने की हिम्मत करते हैं ... "लगभग शून्य"। इसके अलावा, मुझे यकीन नहीं है कि जेवीएम के विकास और जेएलएस के लेखन को कैसे मिलाया जाता है, यानी जो विकास जेएलएस में लिखा है वह कितना दूर तक प्रभावित करता है, लेकिन ... मैं यहां किसी भी अटकल से बचूंगा; -)
मार्को 13

1
मैं अभी भी अपने मामले को आराम देता हूं। देखें कि किसने मेरे दूसरे प्रश्न का उत्तर दिया है :-) यह अब हमेशा के लिए एक आधिकारिक उत्तर के साथ स्पष्ट हो जाएगा, यहां स्टैक ओवरफ्लो पर यह तय किया गया कि तरीकों synchronizedपर समर्थन क्यों नहीं किया गया default
लुकास ईडर

3
@LukasEder मैं देख रहा हूँ, यहाँ वही। कौन उम्मीद कर सकता है कि? कारण विशेष रूप से इस finalसवाल के लिए आश्वस्त कर रहे हैं , और यह कुछ हद तक विनम्र है कि किसी और को समान उदाहरणों के बारे में नहीं लगता था (या, शायद, इन उदाहरणों के बारे में कुछ सोचा था, लेकिन जवाब देने के लिए पर्याप्त आधिकारिक नहीं लगा)। तो अब (क्षमा करें, मुझे यह करना है :) अंतिम शब्द बोला गया है।
19

4

मुझे नहीं लगता कि यह finalएक शालीनता इंटरफ़ेस विधि पर निर्दिष्ट करना आवश्यक है , मैं सहमत हो सकता हूं कि यह मददगार हो सकता है, लेकिन लगता है कि लागतों ने लाभ को कम कर दिया है।

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

कोई भी ऐसा लिख ​​सकता Collectionहै जो इंटरफ़ेस का पालन करता है और फिर उन तरीकों से काम करता है जो बिल्कुल काउंटर सहज हैं, व्यापक इकाई परीक्षण लिखने के अलावा, खुद को उस से ढालने का कोई तरीका नहीं है।


2
Javadoc कॉन्ट्रैक्ट्स मेरे प्रश्न में सूचीबद्ध ठोस उदाहरण के लिए एक वैध वर्कअराउंड हैं , लेकिन सवाल वास्तव में सुविधा इंटरफ़ेस विधि उपयोग-मामले के बारे में नहीं है। प्रश्न एक आधिकारिक कारण के बारे में है कि finalजावा 8 interfaceविधियों पर अनुमति नहीं देने का निर्णय क्यों लिया गया है । अपर्याप्त लागत / लाभ अनुपात एक अच्छा उम्मीदवार है, लेकिन अब तक, यह अटकलें हैं।
लुकास एडर

0

जब हम जानते हैं कि वर्ग हमारे कार्यान्वयन का विस्तार कर सकता है या नहीं कर रहा है, तब हम defaultअपने तरीके से कीवर्ड जोड़ते हैं । लेकिन क्या होगा अगर हम एक ऐसी विधि जोड़ना चाहते हैं जिसे हम लागू करने वाला कोई वर्ग नहीं चाहते हैं? हमारे लिए दो विकल्प उपलब्ध थे:interfaceinterfaceoverride

  1. एक default finalविधि जोड़ें ।
  2. एक staticविधि जोड़ें ।

अब, जावा का कहना है कि अगर हमारे पास classदो या दो से अधिक कार्यान्वयन हैं, तो interfacesउनके पास एक defaultही विधि नाम और हस्ताक्षर के साथ एक विधि है, यानी वे डुप्लिकेट हैं, तो हमें अपनी कक्षा में उस पद्धति का कार्यान्वयन प्रदान करने की आवश्यकता है। अब default finalतरीकों के मामले में , हम एक कार्यान्वयन प्रदान नहीं कर सकते हैं और हम फंस गए हैं। और यही कारण है कि finalकीवर्ड का उपयोग इंटरफेस में नहीं किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.