जावा में कोई निरंतर सुविधा क्यों नहीं है?


140

मैं जावा में स्थिरांक के कारण की पहचान करने की कोशिश कर रहा था मैंने सीखा है कि जावा हमें finalकीवर्ड का उपयोग करके स्थिरांक घोषित करने की अनुमति देता है ।

मेरा सवाल है कि जावा ने एक कॉन्स्टेंट ( const) सुविधा क्यों नहीं शुरू की । चूंकि कई लोग कहते हैं कि यह C ++ से आया है, C ++ में हमारे पास constकीवर्ड है।

कृपया अपने विचार साझा करें।


2
वहाँ है एक constकीवर्ड, लेकिन कोई अंतर्निहित सुविधा है। तदनुसार अपने शीर्षक और टैग को ठीक किया।
लोर्ने की मार्किस

जवाबों:


142

हर बार जब मैं भारी सी ++ कोडिंग से जावा में जाता हूं, तो मुझे जावा में कॉन्स्टिपेशन की कमी के लिए अनुकूल होने में थोड़ा समय लगता है । constC ++ का यह उपयोग निरंतर चर घोषित करने की तुलना में बहुत अलग है, अगर आपको नहीं पता था। अनिवार्य रूप से, यह सुनिश्चित करता है कि एक ऑब्जेक्ट अपरिवर्तनीय है जब एक विशेष प्रकार के पॉइंटर के माध्यम से एक्सेस किया जाता है जिसे एक कॉन्स्ट-पॉइंटर कहा जाता है जब जावा में, उन जगहों पर जहां मैं सामान्य रूप से एक कॉन्स्ट-पॉइंटर वापस करना चाहता हूं, मैं इसके बजाय एक इंटरफ़ेस प्रकार के साथ एक संदर्भ देता हूं केवल ऐसी विधियाँ हैं जिनके दुष्प्रभाव नहीं होने चाहिए। दुर्भाग्य से, यह लैंग्वेज द्वारा लागू नहीं किया गया है।

विकिपीडिया विषय पर निम्नलिखित जानकारी प्रदान करता है:

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


10
finalहालांकि, जावा भी ऐसा ही है।
रीइनियरियरपोस्ट

62
नहीं, यह नहीं है। finalउदाहरण के लिए विधि C ++ constविधियों से पूरी तरह से अलग काम करती है ।
डोमे ०

7
@reinierpost गुण या चर परfinal कीवर्ड केवल यह सुनिश्चित करता है कि एक संपत्ति या चर केवल एक बार सौंपा गया है । उदाहरण के लिए, साइड इफेक्ट के साथ किसी विधि को कॉल करके, इस ऑब्जेक्ट की स्थिति को अभी भी बदल सकता है। एक सूचक के बजाय एक वस्तु को संदर्भित करने के मामले में सी ++ के आवंटन को ढेर करने के लिए कुछ सीमिलर है, लेकिन यह सब है। यह पहले से ही कहा जाने वाला dom0 के अलावा एक टोकोर्स है। final
टिम

9
finalजावा में constमान प्रकार के लिए C ++ की तरह काम करने लगता है , लेकिन T&संदर्भ प्रकारों के लिए C ++ गैर-कॉन्स्टेंस की तरह
मार्क के कोवान

1
फाइनल एक स्किज़ोफ्रेनिक कीवर्ड है। हालांकि यह पुनर्मूल्यांकन को रोकता है, इसका उपयोग चर को बंद करने के लिए उजागर करने के लिए भी किया जाता है। मैं पुनर्मूल्यांकन को रोकना चाहता हूं, लेकिन उन चरों को उजागर नहीं करना चाहता, लेकिन ऐसा करने का कोई तरीका नहीं है। यह मेरी राय में एक नहीं बल्कि खराब माना जाने वाला भाषा फीचर है।
डेविड ब्रैडले

82

क्या करता है const मतलब है
सबसे पहले, महसूस करें कि "कॉन्स्ट" कीवर्ड के शब्दार्थ का अर्थ अलग-अलग लोगों के लिए अलग-अलग चीजें हैं:

  • केवल संदर्भ पढ़ें - जावा finalशब्दार्थ - संदर्भ चर ही दूसरे उदाहरण (स्मृति स्थान) को इंगित करने के लिए आश्वस्त नहीं किया जा सकता है, लेकिन उदाहरण स्वयं ही परिवर्तनीय है
  • पठनीय-केवल संदर्भ - सी constपॉइंटर / संदर्भ शब्दार्थ - इसका अर्थ है कि इस संदर्भ का उपयोग उदाहरण को संशोधित करने के लिए नहीं किया जा सकता है (उदाहरण के लिए चर को निर्दिष्ट नहीं किया जा सकता है, उत्परिवर्तनीय विधियों को आमंत्रित नहीं किया जा सकता) - केवल संदर्भ चर को प्रभावित करता है, इसलिए एक नॉन-कॉस्ट संदर्भ इंगित कर रहा है एक ही उदाहरण उदाहरण को संशोधित कर सकता है
  • अपरिवर्तनीय वस्तु - का अर्थ है कि उदाहरण को स्वयं संशोधित नहीं किया जा सकता है - उदाहरण के लिए लागू होता है, इसलिए किसी भी गैर-कॉन्स्टेबल संदर्भ को अनुमति नहीं दी जाएगी या उदाहरण को संशोधित करने के लिए उपयोग नहीं किया जा सकता है
  • उपरोक्त में से कुछ संयोजन ?
  • अन्य ?

क्यों या क्यों नहीं const
दूसरा, यदि आप वास्तव में "समर्थक" बनाम "कॉन" तर्कों में से कुछ में खुदाई करना चाहते हैं, तो वृद्धि (RFE) "बग" के लिए इस अनुरोध के तहत चर्चा देखें। यह RFE एक "पठनीय-केवल संदर्भ" -टाइप "कॉन्स्ट" सुविधा का अनुरोध करता है। 1999 में खोला गया और फिर 2005 में सूर्य द्वारा बंद / अस्वीकृत कर दिया गया, "कॉन्स्ट" विषय पर जोरदार बहस हुई:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070

हालांकि दोनों पक्षों में बहुत सारे अच्छे तर्क हैं, कुछ के बारे में उद्धृत (लेकिन अनिवार्य रूप से सम्मोहक या स्पष्ट रूप से कटौती नहीं) const शामिल नहीं शामिल हैं:

  • भ्रामक अर्थ विज्ञान इसका दुरुपयोग किया जा सकता है और / या गाली दी हो सकता है (देखें क्या constमतलब ऊपर)
  • डुप्लिकेट क्षमता अन्यथा उपलब्ध हो सकती है (जैसे एक अपरिवर्तनीय वर्ग का डिज़ाइन करना, एक अपरिवर्तनीय इंटरफ़ेस का उपयोग करना)
  • फ़ीचर रेंगना हो सकता है, जिससे अन्य अर्थ परिवर्तन की आवश्यकता हो सकती है जैसे कि मूल्य द्वारा वस्तुओं को पारित करने के लिए समर्थन

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


2
+1 आपके उत्तर के दूसरे भाग के लिए। कई खोजशब्दों में गैर-तुच्छ शब्दार्थ हैं। क्या volatileयह समझना सरल है? या final? भावहीन।
ईनपोकलम

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

7

const C ++ में इसका मतलब यह नहीं है कि एक मान एक स्थिर है।

const C ++ में तात्पर्य है कि एक अनुबंध का ग्राहक इसके मूल्य में परिवर्तन नहीं करने का वचन देता है।

constयदि आप एक ऐसे वातावरण में अभिव्यक्ति के मूल्य को अधिक स्पष्ट करते हैं, यदि आप एक ऐसे वातावरण में हैं जो थ्रेड आधारित संगामिति का समर्थन करता है।

चूंकि जावा को थ्रेड और लॉक कंसीडर को सपोर्ट करने के लिए शुरू से डिज़ाइन किया गया था, इसने शब्द को अधिलेखित करके भ्रम को नहीं जोड़ा final

उदाहरण के लिए:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

आउटपुट 42 तो 7।

हालांकि x, constएक गैर-कांस्टेबल उपनाम के रूप में चिह्नित किया गया है , xएक स्थिर नहीं है। volatileइस व्यवहार के लिए प्रत्येक कंपाइलर की आवश्यकता नहीं होती है (हालाँकि प्रत्येक कंपाइलर को स्थिरांक को अनुमति दी जाती है)

अधिक जटिल प्रणालियों के साथ आपको बिना उपयोग के कॉन्स्टेबल / नॉन-कास्ट एलियास const_castमिलते हैं, इसलिए यह सोचने की आदत में पड़ना कि कॉन्स्ट का मतलब कुछ नहीं होगा और अधिक खतरनाक हो जाएगा। constइसका मतलब केवल यह है कि आपका कोड बिना कास्ट के इसे बदल नहीं सकता है, न कि यह कि मान स्थिर है।


3
const int x = 42; - x एक स्थिरांक है

2
@Neil यदि आपके पास एक ऑब्जेक्ट या वैरिएबल है जो कॉन्स्ट और नॉन-कॉस्ट पॉइंटर्स दोनों द्वारा अलियास किया जाता है, तो कॉन्स एलियास का मूल्य नॉन-कॉस्ट एलियास द्वारा बदला जा सकता है। इसलिए constइसका मतलब यह नहीं है कि एक मूल्य स्थिर है। इसका मतलब यह है कि एक मूल्य का ग्राहक विवश है कि वह इसे म्यूट न करे। आपके उदाहरण में कोई अन्य नहीं है, इसलिए सभी उपयोगकर्ता एक ही बाधा के अधीन हैं। यह सामान्य रूप से ऐसा नहीं है। constग्राहकों को प्रभावित करता है, मूल्य नहीं - यह कहता है कि आप इसे बदल नहीं सकते, ऐसा नहीं है कि यह नहीं बदलेगा।
पीट किरकम

1
कॉन्स्ट-करेक्शन इस बारे में है कि प्रोग्रामर को क्या करना चाहिए , न कि वे क्या कर सकते हैं । मुझे लगता है कि आप सभी को वह बात मिल गई होगी। बस सेंट कि कारण पाठक के हित के लिए हो सकता है के एक जोड़े जोड़ना चाहते थे: की तरह डिजाइन पैटर्न immutable interfaceऔर immutable objectएक और तरीका है जावा में नकल स्थिरांक को (कास्ट और प्रतिबिंब के साथ हराया जा सकता है)। "ट्रू" कॉन्स्ट को SealedObject के साथ किया जा सकता है , अफसोस यह हमारी वस्तु के उपयोग के मामले को नष्ट कर देता है।
मार्टिन एंडरसन

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

1
एक जन्म-से-निरंतर मूल्य को संशोधित करना अपरिभाषित व्यवहार है। आपकी डिस्क पहले से ही स्वरूपित हो सकती है।
झिया यांग

5

यह एक पुराना सवाल है, लेकिन मुझे लगा कि मैं अपने 2 सेंट का योगदान किसी भी तरह से करूंगा क्योंकि आज यह बातचीत हुई है।

यह बिल्कुल जवाब नहीं देता कि कोई कमी क्यों नहीं है? लेकिन अपनी कक्षाओं को अपरिवर्तनीय कैसे बनाया जाए। (दुर्भाग्य से मुझे स्वीकृत जवाब के लिए टिप्पणी के रूप में पोस्ट करने के लिए अभी तक पर्याप्त प्रतिष्ठा नहीं है)

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

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

आइटम 15 बलोच में सुझाव दिया गया है कि आपको ऑब्जेक्ट की स्थिति सुनिश्चित करने के लिए कक्षाओं की पारस्परिकता को सीमित करना चाहिए।

पुस्तक को सीधे उद्धृत करने के लिए:

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

बलोच ने 5 सरल नियमों का पालन करके अपनी कक्षाओं को अपरिवर्तनीय बनाने का वर्णन किया है:

  1. ऑब्जेक्ट की स्थिति को संशोधित करने वाली कोई विधि प्रदान न करें (अर्थात, बसने वाले, उर्फ म्यूटेटर )
  2. सुनिश्चित करें कि कक्षा को बढ़ाया नहीं जा सकता है (इसका अर्थ है कि कक्षा को ही घोषित करना final)।
  3. सभी क्षेत्र बनाओ final
  4. सभी क्षेत्र बनाओ private
  5. किसी भी परिवर्तनशील घटकों के लिए विशेष पहुंच सुनिश्चित करें। (वस्तुओं की रक्षात्मक प्रतियां बनाकर)

अधिक जानकारी के लिए मैं पुस्तक की एक प्रति लेने की सलाह देता हूं।


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

3

C ++ के शब्दार्थ constजावा से बहुत अलग हैं final। यदि डिजाइनरों ने इसका उपयोग constकिया होता तो यह अनावश्यक रूप से भ्रमित होता।

तथ्य यह constहै कि एक आरक्षित शब्द बताता है कि डिजाइनरों को लागू करने के लिए विचार थे const, लेकिन उन्होंने तब से इसके खिलाफ फैसला किया है; इस बंद बग को देखें । वर्णित कारणों में शामिल है कि C ++ शैली के लिए समर्थन जोड़ने से constसंगतता समस्याएं हो सकती हैं।


-1

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


क्या आप कृपया इसका कुछ उदाहरण प्रदान कर सकते हैं?
NO_NAME

वर्ग MYString लागू हो जाता है GetString {निजी अंतिम स्ट्रिंग आगा; सार्वजनिक स्ट्रिंग getString (); } वर्ग MutableString लागू करता है GetString {निजी स्ट्रिंग aaaa2; सार्वजनिक स्ट्रिंग getString (); public String setString ()}
user1122069

-2

स्थिरांक को परिभाषित करने के दो तरीके होंगे - constऔर static final, ठीक उसी शब्दार्थ के साथ। इसके अलावा static finalव्यवहार से बेहतर वर्णन करता हैconst


@Bozho, आपने कॉन्स्ट की तुलना में बेहतर व्यवहार कहा, यह किस तरह से है? क्या आप किसी भी उदाहरण को साझा कर सकते हैं
gmhk

ठीक है, चर static(विशेष उदाहरण से संबंधित नहीं है) और final- बदला नहीं जा सकता।
बूझो

-2

आप कास्ट के समान काम करने वाले कुछ बनाने के लिए स्थैतिक फाइनल का उपयोग कर सकते हैं, मैंने अतीत में इसका उपयोग किया है।

protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;

public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;

अफवाह-आधारित अनुकूलन के लिए नीचा दिखाया गया क्योंकि मैंने एक अफवाह सुनी कि यह एक अप्रभावी रणनीति है।
19

मैंने जवाब से अफवाह को हटा दिया। आप अभी भी स्थैतिक अंतिम int का उपयोग कास्ट स्टाइल कोड बनाने के लिए कर सकते हैं।
हामिश

ठीक है, मैंने अपना डाउनवोट हटा दिया है। हो सकता है कि कुछ अन्य डाउनवोट स्विच स्टेटमेंट के बारे में हों (इसका आपके बाकी उदाहरणों से क्या
लेना

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