रैपर क्लास और आदिम प्रकार का उपयोग कब करें


98

जब मुझे आदिम प्रकारों पर आवरण वर्ग के लिए जाना चाहिए? या मुझे किस परिस्थिति में रैपर / आदिम प्रकारों के बीच चयन करना चाहिए?


1
w3resource.com/java-tutorial/java-wrapper-classes.php यह आलेख इस चर्चा के लिए उपयोगी होगा।
पंकज

जवाबों:


69

दूसरों ने उल्लेख किया है कि कुछ निर्माण जैसे कि Collections कि वस्तुओं की आवश्यकता होती है और यह कि वस्तुएं अपने आदिम समकक्षों (मेमोरी और बॉक्सिंग) से अधिक ओवरहेड होती हैं।

एक और विचार है:

राज्य या कार्य को इंगित करने के लिए किसी विधि / निर्माणकर्ता में वस्तुओं को प्रारंभ करना nullया nullपैरामीटर भेजना आसान हो सकता है । यह आदिम के साथ नहीं किया जा सकता है।

कई प्रोग्रामर इसे सूचित करने के लिए संख्याओं को 0 (डिफ़ॉल्ट) या -1 से प्रारंभ करते हैं, लेकिन परिदृश्य के आधार पर, यह गलत या भ्रामक हो सकता है।

यह तब भी दृश्य सेट करेगा NullPointerExceptionजब कुछ गलत तरीके से उपयोग किया जा रहा है, जो लाइन के नीचे कुछ मनमाने बग की तुलना में बहुत अधिक प्रोग्रामर-अनुकूल है।


15
"यह वस्तुओं को शून्य करने के लिए शुरू करने के लिए आसान हो सकता है"। यह उपयोगी नहीं हो सकता क्योंकि यह गलत है, यदि फ़ील्ड वैकल्पिक है तो आपको यह स्पष्ट रूप से इंगित करना चाहिए।
एडी जैमसेशन

8
lol @EddieJamsession धन्यवाद, मैं फिर से अशक्त करने के लिए शुरू नहीं होगा। (pfffft)
pstanton

@EddieJamsession यदि वास्तविक मूल्य सेट करते समय विफलता को इंगित करने के तरीके के रूप में ऑब्जेक्ट्स को प्रारंभ करना विफल हो गया है, तो आप इस समस्या को कैसे पकड़ेंगे? ओह, मुझे अभी पता चला है कि मैं यह टाइप करता हूं: अपवाद। NullPointerException बहुत सामान्य है; यह बताने के लिए बहुत विशिष्ट कस्टम अपवादों का उपयोग करना बेहतर होगा कि क्या गलत हुआ है। अच्छा, मैं अब से ...
कलार

1
@EddieJamsession मामले पर पढ़ने के बाद, मैंने एक वैकल्पिक वस्तु की अवधारणा में भाग लिया है। सही।
कलार

18

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


3
प्रदर्शन हिट इतना शानदार नहीं है कि कोड की सुगमता / विश्वसनीयता को पीछे ले जाना चाहिए।
पस्टनटॉन

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

1
@pstanton: कृपया बताएं कि कैसे Integerअधिक से अधिक सुपाठ्य है int
स्टीफन सी

कई मामलों में इंटीजर इंट की तुलना में अधिक सुपाठ्य नहीं है और इन मामलों में मैं हमेशा int का उपयोग करूंगा, या अगर मुझे पता है कि एक निश्चित चर कभी भी शून्य नहीं होगा, तो मैं int का उपयोग करूंगा क्योंकि int जैसा कि आपने थोड़ा और कुशल बताया है। हालांकि, कई मामलों में किसी अन्य प्रोग्रामर के लिए किसी वस्तु का उपयोग करने पर किसी वैरिएबल की स्थिति को समझना आसान होता है, क्योंकि इसे यह संकेत देने के लिए अशक्त करने के लिए प्रारंभ किया जा सकता है कि यह तैयार नहीं है। उदाहरण के लिए यदि आपके पास एक बिना सहेजा गया डेटाबेस रिकॉर्ड है, जिसमें एक यूनिक इंक्रीमेंटिंग न्यूमेरिक आईडी है, तो क्या यह वैध आईडी असाइन किए जाने से पहले यह आईडी 0, -1 या शून्य होना चाहिए? उस स्थिति में ऑब्जेक्ट बेहतर होते हैं।
पेस्टनन

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

12

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

1।

class Person {
   int SSN ; // gets initialized to zero by default 
}

2।

class PersonBetter {
  Integer SSN; //gets initialized to null by default
}

पहले मामले में, आप SSN मूल्य को अनधिकृत नहीं रख सकते। यदि आप इसका उपयोग करने का प्रयास करने से पहले मान सेट कर रहे थे तो यह आपको नुकसान पहुंचा सकता है।

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


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

8

मैं केवल रैपर प्रकारों का उपयोग करूंगा यदि आपको करना है।

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

और, आप स्मृति उपयोग और बॉक्सिंग / अनबॉक्सिंग में बिताए गए ओवरहेड खो देते हैं।


4
आप बहुत कुछ हासिल नहीं कर सकते हैं, लेकिन आप बहुत अधिक नहीं खोते हैं। जब तक आप 1990 के पॉम पायलट पर नहीं चल रहे।
पस्टनटॉन

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

4

व्यावहारिक रूप से मुझे ऐसी स्थिति का सामना करना पड़ा जहां आवरण वर्ग के उपयोग के बारे में बताया जा सकता है।

मैंने एक सेवा वर्ग बनाया जिसमें एक longप्रकार का चर था

  1. यदि चर प्रकार का है long - जब आरंभीकृत नहीं किया जाता है, तो इसे 0 पर सेट किया जाएगा - यह GUI में प्रदर्शित होने पर उपयोगकर्ता को भ्रमित करेगा
  2. यदि वैरिएबल टाइप का है Long- जब इनिशियलाइज़ नहीं किया जाता है, तो इसे सेट किया जाएगा null- यह शून्य मान GUI में दिखाई नहीं देगा।

यह उन पर भी लागू होता है Booleanजहां मान अधिक भ्रामक हो सकते हैं जब हम आदिम का उपयोग करते हैं boolean(जैसा कि डिफ़ॉल्ट मान गलत है)।


3

संग्रह सरल जावा आवरण वस्तुओं के लिए विशिष्ट मामला है। हालाँकि, आप कोड (मान ऑब्जेक्ट) में रैपर को अधिक विशिष्ट अर्थ देने पर विचार कर सकते हैं।

IMHO लगभग हमेशा एक फायदा होता है जब यह कोड की पठनीयता और बनाए रखने के लिए मूल्य वस्तुओं का उपयोग करता है। वस्तुओं के अंदर सरल डेटा संरचनाओं को लपेटना जब उनके पास कुछ जिम्मेदारियां होती हैं, तो अक्सर कोड को सरल करता है। यह कुछ ऐसा है जो Domain-Driven Design में बहुत महत्वपूर्ण है

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


3

संख्यात्मक गणनाओं पर हावी होने वाले अनुप्रयोगों का प्रदर्शन आदिम के उपयोग से बहुत लाभ उठा सकता है।

आदिम प्रकार, एक == ऑपरेटर का उपयोग करता है, लेकिन आवरण के लिए पसंदीदा विकल्प बराबर () विधि को कॉल करना है।

"आदिम प्रकार को हानिकारक माना जाता है" क्योंकि वे प्रक्रियात्मक शब्दार्थों को एक समान रूप से एक समान वस्तु-उन्मुख मॉडल में मिलाते हैं।

कई प्रोग्रामर इसे सूचित करने के लिए संख्याओं को 0 (डिफ़ॉल्ट) या -1 से प्रारंभ करते हैं, लेकिन परिदृश्य के आधार पर, यह गलत या भ्रामक हो सकता है।


1

यदि आप संग्रह का उपयोग करना चाहते हैं, तो आपको Wrapper कक्षाओं का उपयोग करना चाहिए

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

ऑटोबॉक्सिंग के बाद से, "कब से प्रिमिटिव या रैपर का उपयोग करना है" फ्रंटियर काफी फजी हो गया है।

लेकिन याद रखें, रैपर्स ऑब्जेक्ट हैं, इसलिए आपको सभी फैंसी जावा फीचर मिलते हैं। उदाहरण के लिए, आप इंटेगर ऑब्जेक्ट बनाने के लिए रिफ्लेक्शन का उपयोग कर सकते हैं, लेकिन इंट वैल्यू नहीं। रैपर क्लासेस में भी वैल्यूऑफ जैसे तरीके होते हैं।


संग्रह के अलावा, मुझे रैपर कक्षाओं का उपयोग नहीं करना चाहिए? कैसे साधारण घोषणा के लिए इसका उपयोग करने के बारे में जैसे कि इंटेगर i = नया इंटेगर (10); क्या ऐसा करना अच्छा है?
गोपी

autoboxing आपको Integer i = 10 करने की अनुमति देता है;
टॉम 25

1
नहीं, श्री। यदि आपको कोई आवश्यकता नहीं है कि मैं एक वस्तु हूं, तो इसे एक न बनाएं।
मैथ्यू फ्लशेन

Autoboxing उपरोक्त i को i = 10 या Integer i = 10 के रूप में घोषित करेगा?
गोपी

3
int pi = new Integer (10); काम करता है। इंगर ओय = 10; काम करता है। int ni = null; काम नहीं करता है। आरएचएस की आवश्यकता के लिए एलएचएस को परिवर्तित किया जाता है।
पस्टनटॉन

0

यदि आप एक मूल्य प्रकार बनाना चाहते हैं। एक ProductSKU या AirportCode की तरह कुछ।

जब एक आदिम प्रकार (मेरे उदाहरण में स्ट्रिंग) समानता को परिभाषित करता है, तो आप समानता को ओवरराइड करना चाहेंगे।


5
स्ट्रिंग एक आदिम नहीं है
pstanton

2
मूल्य प्रकार को लपेटने के लिए अभी भी अच्छे कारण हैं जिनमें आधार ऑब्जेक्ट के रूप में एक स्ट्रिंग शामिल है।
क्रिस मिसल

आपका जवाब सिर्फ मतलब नहीं है। मुझे यकीन नहीं है कि आप क्या कह रहे हैं। मैं आपकी टिप्पणी से सहमत हूं, हालांकि, यदि वे विरासत में सुधार करते हैं, तो रैपर कक्षाएं एक अच्छा विचार हैं।
pstanton

मान प्रकार या मान ऑब्जेक्ट बनाया जाना चाहिए और अपरिवर्तनीय होना चाहिए। उदाहरण के लिए, यह "कंटकोड" ऑब्जेक्ट बनाने के लिए समझ में नहीं आता है: जैसे: नया कंट्रीकोड ("यूएसए") फिर उसी तरह एक और ऑब्जेक्ट बनाएं, जहां बाद में वे अलग हैं। वे शुरू करने के लिए सिर्फ तार हैं, लेकिन उनके पीछे अर्थ है। स्ट्रिंग्स का उपयोग करके, आप उन्हें संशोधित कर सकते हैं (अधिक डेटा, आदि जोड़कर) लेकिन वे अब समान नहीं होंगे। इस लेख के बेहतर विवरण के लिए देखें कि मैं क्या समझाने की कोशिश कर रहा हूँ :) मुझे उम्मीद है कि यह समझ में आता है c2.com/cgi/wiki?ValueObject
क्रिस मिसल

0

जावा में आदिम मूल्य वस्तु नहीं हैं। ऑब्जेक्ट के रूप में इन मूल्यों में हेरफेर करने के लिए java.lang पैकेज प्रत्येक आदिम डेटा प्रकार के लिए एक आवरण वर्ग प्रदान करता है।

सभी रैपर कक्षाएं अंतिम हैं। आरंभ किए जा सकने वाले सभी आवरण वर्गों की वस्तु अपरिवर्तनीय है अर्थात आवरण वस्तु में मूल्य को नहीं बदला जा सकता है।

हालाँकि, शून्य वर्ग को एक आवरण वर्ग माना जाता है, लेकिन यह किसी भी आदिम मूल्यों को लपेटता नहीं है और यह अयोग्य नहीं है। इसमें सार्वजनिक निर्माता नहीं है, यह केवल कीवर्ड शून्य का प्रतिनिधित्व करने वाली एक क्लास ऑब्जेक्ट को दर्शाता है।

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