हम जावा में ऑटोबॉक्सिंग और अनबॉक्सिंग का उपयोग क्यों करते हैं?


81

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

तो हमें इसकी आवश्यकता क्यों है और हम जावा में ऑटोबॉक्सिंग और अनबॉक्सिंग का उपयोग क्यों करते हैं?


1
मूल रूप से जेनरिक के लिए ..
nachokk

3
Integerहै parseIntविधि। intनहीं है। :)
विशाल जंज़ुकिया

@VishalZanzrukia तो बस अधिक कार्यक्षमता प्राप्त करने के लिए?

12
आपके पास हो सकता है List<Integer>, लेकिन आपके पास नहीं हो सकता List<int>
विशाल जंज़ुर्किया

हां..सच में.. अधिक कार्यक्षमता पाने के लिए
विशाल जंज़ुकिया

जवाबों:


173

इसके पीछे के मुख्य कारण को समझने के लिए कुछ संदर्भ की आवश्यकता होती है।

आदिम बनाम वर्ग

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

दूसरी ओर, वर्ग चर में उदाहरणों के संदर्भ होते हैं । संदर्भ आमतौर पर कई भाषाओं में संकेत (या कुछ बहुत समान बिंदुओं के समान) के रूप में कार्यान्वित किए जाते हैं। ये चीजें आम तौर पर एक ही आकार की होती हैं, चाहे वे उदाहरणों के आकार की परवाह किए बिना हों Object, ( String,Integer , आदि)।

वर्ग चर की यह संपत्ति उन संदर्भों को बनाती है जिनमें वे विनिमेय होते हैं (एक हद तक)। यह हमें वह करने की अनुमति देता है जिसे हम प्रतिस्थापन कहते हैं : मोटे तौर पर किसी अन्य प्रकार के उदाहरण के रूप में, संबंधित प्रकार के उपयोग के लिए (एक के Stringरूप में उपयोग करें)Object उदाहरण के लिए, )।

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

जेनरिक और टाइप इरेज़र

जेनेरिक प्रकार एक या अधिक प्रकार के मापदंडों के साथ प्रकार होते हैं (सटीक संख्या को जेनेरिक एरिटी कहा जाता है )। उदाहरण के लिए, जेनेरिक प्रकार की परिभाषा List<T> में एक प्रकार का पैरामीटर होता है T, जो हो सकता है Object(एक ठोस प्रकार का निर्माण List<Object>), String( List<String>), Integer( )List<Integer> ) और इसी तरह हो सकता है।

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

दोनों को एक साथ रखना

अब समस्या उपरोक्त वास्तविकताओं का संयोजन है: यदि सभी मामलों में List<T>हो जाता List<Object>है, तो Tहमेशा एक प्रकार होना चाहिए जिसे सीधे सौंपा जा सकता हैObject । किसी और चीज की अनुमति नहीं दी जा सकती। के बाद से, के रूप में हम ने कहा कि इससे पहले कि, int, floatऔर doubleसाथ परस्पर विनिमय नहीं कर रहे हैं Object, वहाँ नहीं एक हो सकता है List<int>, List<float>याList<double> (जब तक कि जेनरिक के एक काफी अधिक जटिल कार्यान्वयन JVM में ही अस्तित्व में)।

लेकिन जावा प्रकारों की पेशकश करता है Integer, Floatऔर Doubleजो इन प्राथमिकताओं को वर्ग उदाहरणों में लपेटते हैं, जिससे उन्हें प्रभावी रूप से प्रतिस्थापित किया जा सकता है Object, इस प्रकार जेनेरिक प्रकारों को अप्रत्यक्ष रूप से साथ ही साथ काम करने की अनुमति मिलती है (क्योंकि आपके पास हो सकता है List<Integer>, List<Float>)List<Double> और इतने पर)।

A , a, from a आदि Integerसे बनाने की प्रक्रिया को बॉक्सिंग कहा जाता है । रिवर्स को अनबॉक्सिंग कहा जाता है । क्योंकि हर बार जब आप उन्हें उपयोग करना चाहते हैं, तो बॉक्स प्राइमेटिव्स असुविधाजनक होने के बावजूद , ऐसे मामले हैं जहां भाषा स्वचालित रूप से ऐसा करती है - जिसे ऑटोबॉक्सिंग कहा जाता हैintFloatfloatObject


आपकी व्याख्या के अनुसार, हमें जेनेरिक को लागू करने के लिए इन वर्गों इंटेगर, स्ट्रिंग, ... की आवश्यकता है। क्या कोई और कारण है?
बिस्वास मिश्र

1
@BishwasMishra हमारे पास हैं ताकि हम इन मूल्यों को Objectउदाहरण के रूप में उपयोग कर सकें । प्रकार के क्षरण के माध्यम से जेनरिक उसी का एक अनुप्रयोग है।
थिओडोरोस चट्जीगानियाकिस

16

ऑटो बॉक्सिंग का उपयोग आदिम डेटा प्रकारों को उनकी आवरण श्रेणी की वस्तुओं में बदलने के लिए किया जाता है। रैपर क्लास आदिम प्रकारों पर प्रदर्शन करने के लिए एक विस्तृत श्रृंखला प्रदान करती है। सबसे आम उदाहरण है:

int a = 56;
Integer i = a; // Auto Boxing

इसकी जरूरत है आसान सीधे लिखने कोड और JVM करने में सक्षम मुक्केबाजी और अनबॉक्सिंग का ख्याल रखेंगे हो सकता है क्योंकि प्रोग्रामर की।

जब हम java.util.Collection प्रकारों के साथ काम कर रहे होते हैं तब ऑटो बॉक्सिंग भी काम आती है। जब हम आदिम प्रकारों का एक संग्रह बनाना चाहते हैं तो हम सीधे एक आदिम प्रकार का संग्रह नहीं बना सकते हैं, हम केवल वस्तुओं का संग्रह बना सकते हैं। उदाहरण के लिए :

ArrayList<int> al = new ArrayList<int>(); // not supported 

ArrayList<Integer> al = new ArrayList<Integer>(); // supported 
al.add(45); //auto Boxing 

आवरण कक्षाएं

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

रैपर कक्षाओं का उपयोग

String s = "45";
int a = Integer.parseInt(s); // sets the value of a to 45.

कई उपयोगी कार्य हैं जो रैपर कक्षाएं प्रदान करते हैं। यहां जावा डॉक्स देखें

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

Integer s = 45;
int a = s; auto UnBoxing;

संग्रह के मामले में जो केवल ऑटो अनबॉक्सिंग के साथ काम करते हैं, उनका उपयोग किया जाता है। ऐसे :

ArrayList<Integer> al = new ArrayList<Integer>();
al.add(45);

int a = al.get(0); // returns the object of Integer . Automatically Unboxed . 

4

आदिम (गैर-वस्तु) प्रकार की दक्षता में औचित्य है।

आदिम प्रकार int, boolean, doubleतत्काल डेटा हैं, जबकि Objectएस संदर्भ हैं। इसलिए फ़ील्ड (या चर)

int i;
double x;
Object s;

स्थानीय स्मृति 4 + 8 + 8 की आवश्यकता होगी? जहाँ ऑब्जेक्ट के लिए केवल रेफरेंस (पता) को मेमोरी में रखा जाता है।

ऑब्जेक्ट रैपर Integer, Doubleऔर अन्य का उपयोग करते हुए , कोई एक अप्रत्यक्ष परिचय देता है, कुछ मेमोरी में कुछ इंटीजर / डबल उदाहरण का संदर्भ देता है।

मुक्केबाजी की आवश्यकता क्यों है?

यह सापेक्ष दायरे का सवाल है। भविष्य के जावा में यह ArrayList<int>आदिम प्रकार उठाने में सक्षम होने की योजना है ।

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

यहाँ जावा अपने खाके के साथ पारंपरिक C ++ से भिन्न है: C ++ वर्ग vector<string>, vector<int> दो संकलन उत्पाद बनाएगा। जावा डिजाइन एक ArrayList.class होने के लिए गया, हर पैरामीटर के लिए नए संकलित उत्पाद की आवश्यकता नहीं है।

तो बॉक्सिंग के बिना ऑब्जेक्ट के लिए एक पैरामीटर प्रकार की प्रत्येक घटना के लिए कक्षाओं को संकलित करने की आवश्यकता होगी। कॉन्क्रीटो में: हर संग्रह या कंटेनर क्लास को ऑब्जेक्ट, इंट, डबल, बूलियन के लिए एक संस्करण की आवश्यकता होगी। ऑब्जेक्ट के लिए संस्करण सभी बाल वर्गों को संभालेगा।

वास्तव में, इस तरह के विविधीकरण की आवश्यकता पहले से ही जावा एसई में IntBuffer, CharBuffer, DoubleBuffer के लिए मौजूद थी ... जो int, char, double पर काम करती हैं। यह इन स्रोतों को एक आम से उत्पन्न करके एक हैक तरीके से हल किया गया था ।


4

JDK 5 के साथ शुरू, java ने दो महत्वपूर्ण कार्य जोड़े हैं: ऑटोबॉक्सिंग और ऑटोऑनबॉक्सिंग। ऑटोबॉक्सिंग वह प्रक्रिया है जिसके लिए जब भी ऐसी वस्तु की आवश्यकता होती है तो एक रैपर समरूप आवरण में स्वत: ही समा जाता है। आपको स्पष्ट रूप से किसी ऑब्जेक्ट का निर्माण करने की आवश्यकता नहीं है। ऑटो-अनबॉक्सिंग एक ऐसी प्रक्रिया है जिसके तहत एक एनकैप्सुलेटेड ऑब्जेक्ट का मान स्वचालित रूप से एक प्रकार के आवरण से निकाला जाता है जब इसके मूल्य की आवश्यकता होती है। आपको intValue () या doubleValue () जैसी विधि को कॉल करने की आवश्यकता नहीं है ।

ऑटोबॉक्सिंग और ऑटो-अनबॉक्सिंग के अलावा बहुत ही एल्गोरिदम लेखन को सरल करता है , मैन्युअल रूप से बॉक्सिंग और मूल्यों के अनबॉक्सिंग को समाप्त करता है। गलतियों से बचने में भी मददगार है । यह जेनरिक के लिए भी बहुत महत्वपूर्ण है , जो केवल वस्तुओं पर काम करते हैं। अन्त में, ऑटोबॉक्सिंग संग्रह फ्रेमवर्क के साथ काम करने की सुविधा प्रदान करता है ।


2

हमारे पास (संयुक्त राष्ट्र) मुक्केबाजी क्यों है?

लेखन कोड बनाने के लिए जहां हम आदिम और उनके ऑब्जेक्ट ओरिएंटेड (OO) विकल्पों को अधिक आरामदायक / कम क्रिया से मिलाते हैं।

हमारे पास आदिम और उनके OO विकल्प क्यों हैं?

आदिम प्रकार वर्ग नहीं हैं (C # के विपरीत), इस प्रकार वे उपवर्ग नहीं हैं Object और उन्हें ओवरराइड नहीं किया जा सकता है।

हमारे पास intप्रदर्शन कारणों से, और OO प्रोग्रामिंग के लाभों के लिए Objectजैसे विकल्प हैं Integer, और एक मामूली बिंदु के रूप में, उपयोगिता स्थिरांक और विधियों के लिए एक अच्छा स्थान है (Integer.MAX_VALUE और Integer.toString(int))।

OO का लाभ जेनरिक ( List<Integer>) के साथ सबसे आसानी से दिखाई देता है , लेकिन यह केवल उसी तक सीमित नहीं है, उदाहरण के लिए:

Number getMeSome(boolean wantInt) {

    if (wantInt) {
        return Integer.MAX_VALUE;
    } else {
        return Long.MAX_VALUE;
    }
}

1

कुछ डेटा संरचनाएं केवल वस्तुओं को स्वीकार कर सकती हैं, कोई आदिम प्रकार नहीं।

उदाहरण: हाशप में कुंजी।

इस प्रश्न को और देखें: HashMap और int कुंजी के रूप में

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


0

क्योंकि वे विभिन्न प्रकार हैं, और एक सुविधा के रूप में। प्रदर्शन संभवतः आदिम प्रकार के होने का कारण है।


0

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

ArrayList<String> strArrayList = new ArrayList<String>(); // is accepted.

ArrayList<int> intArrayList = new ArrayList<int>(); // not accepted.

इंटेगर क्लास एक ऑब्जेक्ट में आदिम प्रकार के इंट के मूल्य को लपेटता है। किसी भी कोड को स्वीकार किया जाता है।

ArrayList<Integer> intArrayList = new ArrayList<Integer>(); // is accepted.

हम ऐड (मान) विधि के साथ एक मूल्य जोड़ सकते हैं। स्ट्रिंग मान जोड़ने के लिए strArrayList कोड में "Hello" कहें

strArrayList.add("Hello");  

और एक int मान जोड़ें 54 हम लिख सकते हैं

intArrayList.add(54);

लेकिन जब हम intArrayList.add (54) लिखते हैं; संकलक निम्न पंक्ति में परिवर्तित होता है

intArrayList.add(Integer.valueOf(54)); 

जैसा कि intArrayList.add (54) उपयोगकर्ता की ओर से आसान और अधिक स्वीकार्य है, इसलिए कंपाइलर कठिन काम करता है जो ` intArrayList.add(Integer.valueOf(54));ऑटोबॉक्सिंग है।

इसी तरह मान को पुनः प्राप्त करने के लिए हम सिर्फ intArrayList.get (0) टाइप करते हैं और कंपाइलर कन्वर्ट होता है <code>intArrayList.get(0).intValue();जो कि ऑटोऑनबॉक्सिंग है।


0

ऑटोबॉक्सिंग: संबंधित रैपर क्लास की एक वस्तु में एक आदिम मूल्य परिवर्तित करना।

अनबॉक्सिंग: एक आवरण प्रकार की एक वस्तु को उसके संबंधित आदिम मूल्य पर परिवर्तित करना

// Java program to illustrate the concept 
// of Autoboxing and Unboxing 
import java.io.*; 

class GFG 
{ 
    public static void main (String[] args) 
    { 
        // creating an Integer Object 
        // with value 10. 
        Integer i = new Integer(10); 

        // unboxing the Object 
        int i1 = i; 

        System.out.println("Value of i: " + i); 
        System.out.println("Value of i1: " + i1); 

        //Autoboxing of char 
        Character gfg = 'a'; 

        // Auto-unboxing of Character 
        char ch = gfg; 
        System.out.println("Value of ch: " + ch); 
        System.out.println("Value of gfg: " + gfg); 

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