Java, जावास्क्रिप्ट, और C # जैसी मेमोरी-मैनेज की हुई भाषाओं ने `new` कीवर्ड को क्यों बनाए रखा?


138

newजावा, जावास्क्रिप्ट, और सी # जैसी भाषाओं में कीवर्ड एक वर्ग का एक नया उदाहरण बनाता है।

यह सिंटैक्स सी ++ से विरासत में मिला है, जहां newविशेष रूप से ढेर पर एक वर्ग के नए उदाहरण को आवंटित करने के लिए उपयोग किया जाता है, और नए उदाहरण के लिए एक सूचक लौटाता है। C ++ में, यह ऑब्जेक्ट बनाने का एकमात्र तरीका नहीं है। आप स्टैक पर एक ऑब्जेक्ट का निर्माण भी कर सकते हैं, बिना उपयोग के new- और वास्तव में, वस्तुओं के निर्माण का यह तरीका C ++ में बहुत अधिक सामान्य है।

इसलिए, C ++ बैकग्राउंड से आते हुए, newजावा, जावास्क्रिप्ट और C # जैसी भाषाओं में कीवर्ड मेरे लिए स्वाभाविक और स्पष्ट था। फिर मैंने पायथन सीखना शुरू किया, जिसमें newकीवर्ड नहीं है । पायथन में, एक उदाहरण का निर्माण कंस्ट्रक्टर को कॉल करके किया जाता है, जैसे:

f = Foo()

सबसे पहले, यह मेरे लिए थोड़ा सा लग रहा था, जब तक यह मेरे लिए नहीं हुआ कि पायथन के पास कोई कारण नहीं है new, क्योंकि सब कुछ एक वस्तु है इसलिए विभिन्न कंस्ट्रक्टर सिंटैक्स के बीच खंडन करने की कोई आवश्यकता नहीं है।

लेकिन फिर मैंने सोचा - वास्तव newमें जावा में क्या बात है ? हमें क्यों कहना चाहिए Object o = new Object();? सिर्फ क्यों नहीं Object o = Object();? C ++ में निश्चित रूप से एक आवश्यकता है new, क्योंकि हमें ढेर पर आवंटित करने और स्टैक पर आवंटित करने के बीच अंतर करने की आवश्यकता है, लेकिन जावा में सभी ऑब्जेक्ट्स को हीप पर बनाया जाता है, इसलिए newकीवर्ड भी क्यों है ? जावास्क्रिप्ट के लिए एक ही सवाल पूछा जा सकता है। C # में, जिसे मैं बहुत कम परिचित हूं, मुझे लगता है कि newवस्तु प्रकार और मूल्य प्रकारों के बीच अंतर करने के संदर्भ में कुछ उद्देश्य हो सकता है, लेकिन मुझे यकीन है।

भले ही, यह मुझे लगता है कि कई भाषाएँ जो C ++ के बाद आईं, उन्हें केवल "विरासत में मिली" newकीवर्ड - बिना इसकी आवश्यकता के। यह लगभग एक शाब्दिक खोजशब्द की तरह है । हमें किसी भी कारण से इसकी आवश्यकता नहीं लगती, और फिर भी यह वहां है।

प्रश्न: क्या मैं इस बारे में सही हूं? या फिर कुछ सम्मोहक कारण है जो newC ++ में होने की आवश्यकता है - जावा, जावास्क्रिप्ट और C # जैसी स्मृति-प्रबंधित भाषाओं से प्रेरित है लेकिन पायथन नहीं है?


13
सवाल यह है कि किसी भी भाषा में newकीवर्ड क्यों है । बेशक मैं एक नया चर, बेवकूफ संकलक बनाना चाहता हूं! मेरी राय में एक अच्छी भाषा में एक वाक्यविन्यास होगा f = heap Foo(), जैसे f = auto Foo()

7
विचार करने के लिए एक बहुत ही महत्वपूर्ण बिंदु यह है कि एक भाषा नए प्रोग्रामर से कितनी परिचित है। जावा को स्पष्ट रूप से C / C ++ प्रोग्रामर से परिचित होने के लिए डिज़ाइन किया गया था।

1
@ लुंडिन: यह वास्तव में संकलक प्रौद्योगिकी का एक परिणाम है। एक आधुनिक संकलक को भी संकेत की आवश्यकता नहीं होगी; यह पता लगाना होगा कि उस चर के वास्तविक उपयोग के आधार पर वस्तु को कहां रखा जाए। यानी जब fफ़ंक्शन से बच नहीं जाता है, तो स्टैक स्पेस आवंटित करें।
9

3
@ लुंडिन: यह कर सकता है, और वास्तव में आधुनिक जेवीएम है। यह केवल यह साबित करने की बात है कि fजब एनक्लोजर फ़ंक्शन वापस आता है तो जीसी ऑब्जेक्ट एकत्र कर सकता है।
MSLERS

1
यह पूछने के लिए रचनात्मक नहीं है कि किसी भाषा को जिस तरह से डिज़ाइन किया गया है, खासकर अगर वह डिज़ाइन हमें बिना किसी स्पष्ट लाभ के चार अतिरिक्त अक्षर लिखने के लिए कहता है? मैं क्या खो रहा हूँ?
मेट्रिक्सफ्रॉग

जवाबों:


93

आपके अवलोकन सही हैं। C ++ एक जटिल जानवर है, और newकीवर्ड का उपयोग किसी ऐसी चीज के बीच अंतर करने के लिए किया गया था , deleteजिसे बाद में जरूरत थी और कुछ ऐसा जिसे स्वचालित रूप से पुनः प्राप्त किया जाएगा। जावा और C # में, उन्होंने deleteकीवर्ड को छोड़ दिया क्योंकि कचरा संग्रहकर्ता आपके लिए इसका ध्यान रखेगा।

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

  • यह शब्दबद्ध रूप से सही था । यदि आप C ++ से परिचित थे, तो आप जानते थे कि newकीवर्ड ढेर पर एक ऑब्जेक्ट बनाता है। तो, अपेक्षित व्यवहार क्यों बदलें?
  • यह इस तथ्य पर ध्यान देता है कि आप एक विधि को कॉल करने के बजाय एक वस्तु को तत्काल कर रहे हैं। Microsoft कोड शैली सिफारिशों के साथ, विधि नाम बड़े अक्षरों से शुरू होते हैं ताकि भ्रम हो सके।

रूबी कहीं न कहीं पायथन और जावा / सी # के बीच है, जिसके उपयोग में है new। मूल रूप से आप इस तरह से एक वस्तु को तुरंत करते हैं:

f = Foo.new()

यह एक कीवर्ड नहीं है, यह क्लास के लिए एक स्टैटिक तरीका है। इसका मतलब यह है कि यदि आप एक सिंगलटन चाहते हैं, तो आप new()हर बार उसी उदाहरण को वापस करने के लिए डिफ़ॉल्ट कार्यान्वयन को ओवरराइड कर सकते हैं । यह आवश्यक रूप से अनुशंसित नहीं है, लेकिन यह संभव है।


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

3
हाँ। हम हालांकि जेनरिक के बारे में बात नहीं करेंगे। Java और C # दोनों के जेनेरिक का संस्करण बहुत ही आपत्तिजनक है। हालांकि C ++ कहना आसान नहीं है। जेनरिक वास्तव में केवल सांख्यिकीय रूप से टाइप की जाने वाली भाषाओं के लिए उपयोगी हैं। डायनामिक रूप से टाइप की गई भाषाएं जैसे पायथन, रूबी और स्मॉलटॉक सिर्फ उनकी जरूरत नहीं हैं।
बेरिन लोरिट्श

2
डेल्फी में रूबी के समान सिंटैक्स है, सिवाय इसके कि कंस्ट्रक्टर आमतौर पर (लेकिन केवल bhy सम्मेलन) हैं जिन्हें क्रिएट (`f: = TFoo.Create (param1, param2 ...) कहा जाता है
Gerry

ऑब्जेक्टिव-सी में, allocविधि (लगभग रूबी के रूप में एक ही चीज new) भी केवल एक वर्ग विधि है।
मियादी

3
भाषा डिजाइन के नजरिए से, कीवर्ड कई कारणों से खराब हैं, मुख्य रूप से आप उन्हें बदल नहीं सकते हैं। दूसरी ओर, विधि की अवधारणा का पुन: उपयोग करना आसान है, लेकिन पार्स और विश्लेषण करते समय कुछ ध्यान देने की आवश्यकता है। स्मॉलटाक और उसके परिजन संदेश, C ++ और दूसरी ओर के कीवर्ड का उपयोग करते हैं
गेब्रियल erčerbák

86

संक्षेप में, आप सही हैं। Keyword new जावा और C # जैसी भाषाओं में शानदार है। यहाँ ब्रूस एकेल की कुछ अंतर्दृष्टि दी गई है जो 1990 के दशक में C ++ स्टैंडर्ड कॉमाइट के सदस्य थे और बाद में उन्होंने जावा पर पुस्तकें प्रकाशित कीं: http://www.artima.com/weblogs/viewpost.jsp?thread=260578

ढेर वस्तुओं से ढेर वस्तुओं को भेद करने के लिए किसी तरह की जरूरत है। इस समस्या को हल करने के लिए, नए कीवर्ड को स्मालटाक से विनियोजित किया गया था। स्टैक ऑब्जेक्ट बनाने के लिए, आप बस इसे घोषित करते हैं, जैसे कि कैट एक्स में; या, तर्कों के साथ, कैट एक्स ("मिट्टेंस") ;; एक ढेर ऑब्जेक्ट बनाने के लिए, आप नए का उपयोग करते हैं, जैसे कि नई बिल्ली में; या नई बिल्ली ("मिट्टेंस"); - बाधाओं को देखते हुए, यह एक सुंदर और सुसंगत समाधान है।

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


2
ढेर बनाम ढेर ... आनंदमय, ऐसा कभी नहीं सोचा होगा।
वर्नरसीडी

1
"प्रकार के निष्कर्ष पर चर्चा की गई है, लेकिन मैं ऐसा नहीं करूँगा कि यह नहीं होगा।" :), खैर, जावा का विकास अभी भी आगे बढ़ता है। दिलचस्प है कि यह जावा 10 के लिए एकमात्र फ्लैगशिप है। varकीवर्ड कहीं नहीं के रूप में अच्छा के रूप में करीब है autoसी ++ में है, लेकिन मुझे आशा है कि यह सुधार होगा।
बजे

15

मेरे विचार से दो कारण हो सकते हैं:

  • new एक वस्तु और एक आदिम के बीच अंतर करता है
  • newवाक्य रचना में थोड़ा और अधिक पठनीय है (IMO)

पहला तुच्छ है। मुझे नहीं लगता कि दोनों को अलग तरह से बताना कोई कठिन काम है। दूसरा ओपी के बिंदु का एक उदाहरण है, जो कि newनिरर्थक है।

हालाँकि, नामस्थान संघर्ष हो सकते हैं; विचार करें:

public class Foo {
   Foo() {
      // Constructor
   }
}

public class Bar {
   public static void main(String[] args) {
      Foo f = Foo();
   }

   public Foo Foo() {
      return Foo();
   }
}

आप कल्पना के बहुत अधिक विस्तार के बिना, आसानी से एक असीम पुनरावर्ती कॉल के साथ समाप्त कर सकते हैं। कंपाइलर को "फ़ंक्शन नाम ऑब्जेक्ट के समान" त्रुटि लागू करना होगा। यह वास्तव में चोट नहीं पहुंचाएगा, लेकिन यह उपयोग करने के लिए बहुत सरल है new, जो बताता है कि Go to the object of the same name as this method and use the method that matches this signature.जावा, पार्स करने के लिए एक बहुत ही सरल भाषा है, और मुझे इस क्षेत्र में सहायता करता है।


1
यह किसी भी अन्य अनंत पुनरावृत्ति के लिए कैसे अलग है?
डेडएमजी

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

10

जावा, एक के लिए, अभी भी सी के ++ विरोधाभास है: नहीं काफी कुछ एक ऑब्जेक्ट है। जावा में अंतर्निहित प्रकार (जैसे, charऔर int) हैं जिन्हें गतिशील रूप से आवंटित नहीं किया जाना है।

इसका मतलब यह नहीं है कि newवास्तव में जावा में आवश्यक है हालांकि - प्रकार के सेट जिन्हें गतिशील रूप से आवंटित करने की आवश्यकता नहीं है, वे निश्चित और ज्ञात हैं। जब आप किसी वस्तु को परिभाषित करते हैं, तो संकलक को पता चल सकता है (और वास्तव में, जानता है) कि क्या यह एक साधारण मूल्य है charया एक वस्तु जिसे गतिशील रूप से आवंटित किया जाना है।

मैं जावा के डिजाइन की गुणवत्ता (या इस मामले में कमी) के बारे में इसका क्या अर्थ है, इस पर विचार करने से मना करूंगा।


इस बिंदु पर, आदिम प्रकारों को किसी भी निर्माता को कॉल करने की आवश्यकता नहीं है - वे या तो एक शाब्दिक के रूप में लिखे गए हैं, एक ऑपरेटर से आते हैं, या कुछ आदिम-रिटर्न फ़ंक्शन से। आप वास्तव में एक के बिना भी तार (जो ढेर पर हैं) बनाते हैं new, तो यह वास्तव में कारण नहीं है।
पाओलो एबरमन

9

जावास्क्रिप्ट में आपको इसकी आवश्यकता है क्योंकि निर्माता एक सामान्य फ़ंक्शन की तरह दिखता है, इसलिए जेएस को यह कैसे पता होना चाहिए कि आप एक नया ऑब्जेक्ट बनाना चाहते हैं यदि यह नए कीवर्ड के लिए नहीं था?


4

दिलचस्प है, वीबी को इसकी आवश्यकता है - के बीच का अंतर

Dim f As Foo

जो बिना किसी वेरिएबल को घोषित करता है, Foo f;C # के बराबर और

Dim f As New Foo()

जो चर की घोषणा करता है और वर्ग का एक नया उदाहरण var f = new Foo();देता है, C # के बराबर , एक विशिष्ट अंतर है। पूर्व- .NET VB में, आप उपयोग भी कर सकते हैं Dim f As Fooया Dim f As New Foo- क्योंकि कंस्ट्रक्टर्स पर कोई ओवरलोडिंग नहीं थी।


4
वीबी को शॉर्टहैंड संस्करण की आवश्यकता नहीं है , यह सिर्फ एक संक्षिप्त नाम है। आप टाइप और कंस्ट्रक्टर डिम ए अस फू = न्यू फू () के साथ लंबा संस्करण भी लिख सकते हैं। ऑप्शन Infer On के साथ, जो C # के संस्करण के लिए निकटतम चीज़ है, आप Dim f = New Foo () लिख सकते हैं और कंपाइलर f के प्रकार को संक्रमित करता है।
मार्कज

2
... और Dim f As Foo()एक वाणी सरणी के Fooरों। ओह खुशी! :-)
हेनजी

@ मर्कज: vb.net में, आशुलिपि समकक्ष है। Vb6 में, यह नहीं था। Vb6 में, Dim Foo As New Barप्रभावी रूप से Fooएक संपत्ति बनाएगा जो निर्माण करेगा Barयदि इसे पढ़ा गया था (यानी Nothing)। यह व्यवहार एक बार होने तक सीमित नहीं था; सेटिंग Fooकरना Nothingऔर फिर इसे पढ़ना एक और नया निर्माण करेगा Bar
सुपरकैट

4

मुझे बहुत सारे उत्तर पसंद हैं और मैं इसे जोड़ना चाहूंगा:
यह कोड को पढ़ना आसान बनाता है
न कि यह स्थिति अक्सर होती है, लेकिन विचार करें कि आप एक क्रिया के नाम पर एक विधि चाहते थे जिसने एक ही नाम को संज्ञा के रूप में साझा किया। सी # और अन्य भाषा में स्वाभाविक रूप से शब्द objectआरक्षित है। लेकिन अगर ऐसा नहीं होता Foo = object()है तो यह ऑब्जेक्ट मेथड कॉल का परिणाम होगा या यह एक नई वस्तु को तुरंत बदल देगा। उम्मीद है कि बिना newकीवर्ड के भाषा में इस स्थिति से सुरक्षा होती है, लेकिन newकंस्ट्रक्टर की कॉलिंग से पहले आपको कीवर्ड की आवश्यकता होती है, आप ऑब्जेक्ट के रूप में एक ही नाम के साथ एक विधि के अस्तित्व की अनुमति देते हैं।


4
यकीनन, यह जानना एक बुरा संकेत है।
डेडएमजी

1
@DeadMG: "आर्ग्यूज़्म" का अर्थ है "मैं तर्क दूंगा कि जब तक बार बंद नहीं हो जाता ..."
डोनल फैलो

3

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

मैं जावास्क्रिप्ट और सी # को अच्छी तरह से कहना नहीं जानता, लेकिन मुझे newजावा में कोई कारण नहीं दिखता है सिवाय इसके कि सी ++ के पास था।


मुझे लगता है कि जावास्क्रिप्ट को "संभवत: जावा की तरह दिखने" के लिए डिज़ाइन किया गया था, तब भी जब यह विशेष रूप से अन-जावा-जैसा कुछ कर रहा हो। x = new Y()जावास्क्रिप्ट में वर्ग को तुरंत नहीं करता है Y, क्योंकि जावास्क्रिप्ट में कक्षाएं नहीं हैं । लेकिन यह जावा की तरह दिखता है इसलिए यह newजावा से कीवर्ड को आगे बढ़ाता है, जो निश्चित रूप से इसे C ++ से आगे ले जाता है।
MatrixFrog

टूटे स्विच के लिए +1 (आशा है कि आप इसकी मरम्मत करते हैं: डी)।
मांर्टिनस

3

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

class Address { 
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

class Person {
    public string Name { get; set; }
    public Address Address { get; set; }

    public void ChangeStreet(string newStreet) {
        Address = new Address { 
            Street = newStreet, 
            City = Address.City,
            State = Address.State,
            Zip = Address.Zip
        };
    }
}

उपयोग नोट की newयह स्पष्ट है कि होने की अनुमति देता Addressहै Addressप्रकार नहीं Addressसदस्य। यह एक सदस्य को अपने प्रकार के समान नाम रखने की अनुमति देता है। इसके बिना आपको नाम टकराने से बचने के लिए प्रकार के नाम को उपसर्ग करने की आवश्यकता होगी, जैसे कि CAddress। यह बहुत ही जानबूझकर किया गया था क्योंकि एंडर्स ने कभी भी मैरी नोटेशन या कुछ भी समान पसंद नहीं किया था और इसके बिना सी # होना चाहते थे। तथ्य यह भी परिचित था कि एक डबल बोनस था।


w00t, और पता तो एक इंटरफ़ेस से प्राप्त किया जा सकता है जिसे एड्रेस कहा जाता है .. केवल, नहीं, यह नहीं हो सकता। तो इसका एक बहुत लाभ नहीं है, एक ही नाम का पुन: उपयोग करने और अपने कोड की सामान्य पठनीयता से कम होने में सक्षम है। इसलिए I को इंटरफेस के लिए रखकर, लेकिन सी को कक्षाओं से हटाकर, उन्होंने बिना किसी व्यावहारिक लाभ के केवल एक गंदा गंध बनाया।
gbjbaanb

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

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

@gbjbaanb कोई गंध नहीं है। यह हमेशा स्पष्ट है कि आप किसी प्रकार या संपत्ति / सदस्य या फ़ंक्शन का उल्लेख कर रहे हैं या नहीं। असली गंध तब होती है जब आप एक नामस्थान को एक वर्ग के रूप में नाम देते हैं। MyClass.MyClass
स्टीफन

0

दिलचस्प बात यह है कि परफेक्ट फॉरवर्डिंग के आगमन के साथ, newC ++ में भी नॉन-प्लेसमेंट की आवश्यकता नहीं है। इसलिए, यकीनन, अब किसी भी उल्लेखित भाषा में इसकी आवश्यकता नहीं है।


4
क्या आप अग्रेषित करना करने के लिए ? अंतत: किसी तरह std::shared_ptr<int> foo();बुलाना पड़ेगा new int
9

0

मुझे यकीन नहीं है कि जावा डिजाइनरों के मन में यह था लेकिन जब आप वस्तुओं को पुनरावर्ती रिकॉर्ड के रूप में सोचते हैं , तो आप कल्पना कर सकते हैं कि Foo(123)कोई वस्तु नहीं लौटाता है, लेकिन एक फ़ंक्शन जिसका निर्धारण बिंदु बनाया जा रहा है। वस्तु यदि इसे तर्क के रूप में दी जा रही वस्तु है)। और इसका उद्देश्य new"गाँठ बाँधना" है और उस निर्धारण को वापस करना है। दूसरे शब्दों newमें "ऑब्जेक्ट-टू-बी" को इसके बारे में पता होगा self

इस तरह के दृष्टिकोण से उदाहरण के लिए विरासत को औपचारिक बनाने में मदद मिल सकती है: आप किसी ऑब्जेक्ट-फ़ंक्शन को किसी अन्य ऑब्जेक्ट-फ़ंक्शन के साथ विस्तारित कर सकते हैं और अंत में उन्हें selfउपयोग करके आम प्रदान कर सकते हैं new:

cp = new (Colored("Blue") & Line(0, 0, 100, 100))

यहाँ &दो ऑब्जेक्ट-फ़ंक्शंस को जोड़ती है।

इस मामले में इस newरूप में परिभाषित किया जा सकता है:

def new(objectFunction) {
    actualObject = objectFunction(actualObject)
    return actualObject
}

-2

'नील' की अनुमति देने के लिए।

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

C ++ में एक लाइन की तरह

Person me;

डिफ़ॉल्ट निर्माता को तुरंत कॉल करेगा।


4
उम, डिफ़ॉल्ट रूप से और गैर-नील के लिए उपयोग Person me = Nilकरने Person meमें निल के साथ क्या गलत है या हो रहा है Person me = Person()? मेरा कहना है कि ऐसा नहीं लगता कि नील इस निर्णय का एक कारक था ...
एंड्रेस एफ।

तुम्हारी बात तथ्य पूर्ण है। व्यक्ति मुझे = व्यक्ति (); समान रूप से अच्छा काम करेगा।
क्रिस वान बाल

@AndresF। या यहां तक ​​कि सरल Person meहोने के साथ शून्य और Person me()डिफ़ॉल्ट कंस्ट्रक्टर को लागू करना। इसलिए आपको हमेशा कुछ भी करने के लिए कोष्ठक की आवश्यकता होगी, और इस तरह एक सी ++ अनियमितता से छुटकारा मिलेगा।
मातरिनस

-2

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

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


-4

वास्तव में जावा में स्ट्रिंग्स का उपयोग करते समय एक अंतर होता है:

String myString = "myString";

से अलग है

String myString = new String("myString");

यह मानते हुए कि "myString"पहले कभी भी स्ट्रिंग का उपयोग नहीं किया गया है, पहला कथन स्ट्रिंग पूल (ढेर का एक विशेष क्षेत्र) में एक एकल स्ट्रिंग ऑब्जेक्ट बनाता है जबकि दूसरा स्टेटमेंट दो ऑब्जेक्ट बनाता है, एक ऑब्जेक्ट के लिए सामान्य हीप क्षेत्र में और दूसरा स्ट्रिंग पूल में। । यह स्पष्ट है कि दूसरा विवरण इस विशेष परिदृश्य में बेकार है, लेकिन भाषा द्वारा स्वीकार्य है।

इसका मतलब यह है कि नए आश्वासन देता है कि ऑब्जेक्ट को ढेर के उस विशेष क्षेत्र में बनाया गया है, जो सामान्य ऑब्जेक्ट के लिए तुरंत आवंटित किया गया है, लेकिन इसके बिना ऑब्जेक्ट को तत्काल करने के अन्य तरीके भी हो सकते हैं; ऊपर वाला एक उदाहरण है, और विस्तार के लिए जगह बची है।


2
लेकिन यह सवाल नहीं था। सवाल था "क्यों नहीं String myString = String("myString");?" ( newकीवर्ड की अनुपस्थिति पर ध्यान दें )
एंड्रेस एफ।

@AndresF। स्पष्ट इम्हो की तरह ... यह स्ट्रिंग नाम की एक विधि है जो एक स्ट्रिंग को एक स्ट्रिंग वर्ग में लौटाती है और इसे कॉल करने और निर्माणकर्ता को कॉल करने के बीच अंतर होना चाहिए। कुछ इस तरहclass MyClass { public MyClass() {} public MyClass MyClass() {return null;} public void doSomething { MyClass myClass = MyClass();}} //which is it, constructor or method?
m3th0dman

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

2
क्षमा करें, मैं आपके तर्क का पालन नहीं करता। आप को प्रभावी ढंग से बहस कर रहे हैं वाक्यविन्यास , अर्थ विज्ञान नहीं है, और वैसे भी प्रश्न के बारे में था newके लिए प्रबंधित भाषाओं । मैंने दिखाया है कि newइसकी बिल्कुल ज़रूरत नहीं है (जैसे कि स्केला को केस क्लासेस के लिए इसकी ज़रूरत नहीं है) और यह भी कि कोई अस्पष्टता नहीं है (क्योंकि आपके पास वैसे भी MyClassक्लास में नाम की कोई विधि नहीं हो सकती MyClassहै)। नहीं है कोई अस्पष्टता के लिए String s = String("hello"); यह एक निर्माणकर्ता के अलावा और कुछ नहीं हो सकता। और अंत में, मैं असहमत हूं: सिंटैक्स को बढ़ाने और स्पष्ट करने के लिए कोड कन्वेंशन हैं, जो आप के बारे में बहस कर रहे हैं!
एंड्रेस एफ।

1
तो यह आपका तर्क है? "जावा डिजाइनरों को newकीवर्ड की आवश्यकता थी क्योंकि अन्यथा जावा का सिंटैक्स अलग होता"? मुझे यकीन है कि आप उस तर्क की कमजोरी देख सकते हैं;) और हाँ, आप वाक्यविन्यास पर चर्चा करते हैं, शब्दार्थ की नहीं। इसके अलावा, क्या के साथ पीछे संगतता ? यदि आप एक नई भाषा डिज़ाइन कर रहे हैं, जैसे कि जावा, तो आप पहले से ही C और C ++ के साथ असंगत हैं!
एंड्रेस एफ।

-8

सी # में ढेर बनाम ढेर पर बनाई गई वस्तुओं के बीच अंतर करना महत्वपूर्ण है। अक्सर हम बेहतर प्रदर्शन के लिए स्टैक पर ऑब्जेक्ट बनाते हैं। देखें, जब स्टैक पर कोई वस्तु दायरे से बाहर जाती है, तो यह तुरंत गायब हो जाता है जब स्टैक बिना किसी आदिम की तरह निकल जाता है। कचरा संग्रहकर्ता को इसकी निगरानी रखने की कोई आवश्यकता नहीं है, और ढेर पर आवश्यक स्थान आवंटित करने के लिए मेमोरी मैनेजर का कोई अतिरिक्त ओवरहेड नहीं है।


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