2012-05-25 15 views
50

ArrayList (या अन्य संग्रह) अंतिम करके हम कौन से फायदे/नुकसान प्राप्त कर सकते हैं? मैं अभी भी ArrayList नए तत्वों में जोड़ सकता हूं, तत्वों को हटा सकता हूं और इसे अपडेट कर सकता हूं। लेकिन इसका प्रभाव क्या है?अंतिम ऐरेलिस्ट की भावना क्या है?

+1

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

उत्तर

103

लेकिन इसका प्रभाव क्या है?

इसका मतलब यह है कि आप एक अलग संग्रह उदाहरण को इंगित करने के चर rebind नहीं कर सकते हैं:

final List<Integer> list = new ArrayList<Integer>(); 
list = new ArrayList<Integer>(); // Since `list' is final, this won't compile 

शैली के एक मामले के रूप में, मैं सबसे संदर्भ है कि मैं के रूप में बदलने के लिए इरादा नहीं है की घोषणा final

मैं अभी भी ऐरेलिस्ट नए तत्वों में जोड़ सकता हूं, तत्वों को हटा सकता हूं और इसे अपडेट कर सकता हूं।

अगर आप चाहें तो आप Collections.unmodifiableList() का उपयोग करके प्रविष्टि, हटाने आदि को रोका जा सकता:

final List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>(...)); 
+3

+1 अंतिम फ़ील्ड का उपयोग स्पष्टता में सुधार कर सकता है क्योंकि कक्षाएं काफी लंबी हो सकती हैं। मैं विधियों में अंतिम रूप से उपयोग नहीं करता क्योंकि मैं लंबी विधियों को तोड़ने की कोशिश करता हूं। –

13

यह सिर्फ मतलब है कि आप नहीं है अपने संदर्भ पुन: असाइन कर सकते हैं। नीचे की तरह कुछ करने का प्रयास करने से संकलक त्रुटि हो जाएगी।

final List<String> list = new ArrayList<String>(); 

list = new LinkedList<String>(); 
    ^
    Compiler error here 

तुम सच में एक अपरिवर्तनीय सूची चाहते हैं, आप Collections.unmodifiableList() विधि का उपयोग करना चाहिए।

7

उदाहरण के लिए आप new ArrayList का उपयोग करके इसके संदर्भ को संशोधित करने में सक्षम नहीं होंगे।

1

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

3

यह प्रभाव नहीं डालता है कि आप ArrayList के साथ क्या कर सकते हैं जैसा कि आप सही तरीके से देखते हैं - ऐरेलिस्ट अभी भी उत्परिवर्तनीय है। आपने अभी संदर्भ को अपरिवर्तनीय बना दिया है।

लेकिन एक चर अंतिम बनाने है अन्य लाभ:

  • यह बदला जा रहा यह निरंतर रहने की उम्मीद है, तो से चर को रोकता है। यह भविष्य की बग को रोकने में मदद कर सकता है।
  • चर बनाने final संकलक कुछ प्रदर्शन अनुकूलन करने में मदद कर सकते हैं।

सामान्य रूप से, अधिक चीजें जिन्हें आप अपरिवर्तनीय बनाते हैं, बेहतर। तो संदर्भ अंतिम बनाते हैं (भले ही वे म्यूटेबल ऑब्जेक्ट्स के संदर्भ हैं) आमतौर पर एक अच्छा विचार है।

1

आप इसे एक अलग संग्रह में पुनर्विचार नहीं कर सकते क्योंकि एक्स ने कहा था।

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

उदाहरण: जब आप उस संदर्भ पर भरोसा करते हैं तो आपको अंतिम की आवश्यकता नहीं होती है। उदाहरण के लिए सिंक्रनाइज़ेशन परिदृश्य में यह सच है।

और अधिक उदाहरण हो सकते हैं। यदि आप संदर्भ को बदलने का इरादा नहीं रखते हैं तो सदस्यों को अंतिम घोषित करना अच्छी शैली है।

5

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

आप Collections.unmodifiableList के उपयोग के साथ final कीवर्ड जोड़ देते हैं तो आप जीई व्यवहार आप शायद प्राप्त करने के लिए कोशिश कर रहे हैं, उदाहरण के लिए:

final List fixedList = Collections.unmodifiableList(someList); 

यह है परिणाम के रूप में है कि सूची की ओर इशारा किया fixedList द्वारा नहीं किया जा सकता बदला हुआ। हालांकि कि यह अभी भी someList संदर्भ के माध्यम से बदल किया जा सकता है खबरदार मैं व्यक्तिगत रूप से मेरी कक्षा के उपयोगकर्ताओं की जाँच से बचाने के लिए final के रूप में मेरी कक्षाओं के संग्रह क्षेत्र को चिह्नित (ताकि यकीन है कि यह इस asignment के बाद क्षेत्र से बाहर है या नहीं।)

1

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

3

final में बहु थ्रेडिंग के तहत बहुत सारे परिणाम हैं।

  1. जेएमएम स्पष्ट रूप से final फ़ील्ड के प्रारंभिक समापन की गारंटी देता है।

क्या स्पष्ट रूप से परिभाषित नहीं कर रहा है है:

  1. संकलनकर्ता उन्हें स्मृति बाधाओं भर में पुन: व्यवस्थित करने के लिए स्वतंत्र हैं।
  2. कंपाइलर हमेशा कैश की गई प्रतिलिपि पढ़ सकते हैं।
1

वास्तव में अपरिवर्तनीय सूची प्राप्त करने के लिए, आपको सूची की सामग्री की गहरी प्रतियां बनाना होगा। UnmodifiableList केवल संदर्भों की सूची कुछ हद तक अपरिवर्तनीय प्रस्तुत करेगा। अब सूची या सरणी की गहरी प्रतिलिपि बनाना बढ़ते आकार के साथ स्मृति पर कठिन होगा। आप धारावाहिक/deserialization का उपयोग कर सकते हैं और सरणी/सूची की गहरी प्रति एक temp फ़ाइल में स्टोर कर सकते हैं। सेटर उपलब्ध नहीं होगा क्योंकि सदस्य व्यवहार्यता अपरिवर्तनीय होने की आवश्यकता है। गेटटर सदस्य चर को एक फ़ाइल में क्रमबद्ध करेगा और फिर गहरी प्रति प्राप्त करने के लिए इसे विलुप्त कर देगा। Seraialization एक वस्तु पेड़ की गहराई में जाने की एक सहज प्रकृति है। यह हालांकि कुछ प्रदर्शन लागत पर पूर्ण अपरिवर्तनीयता सुनिश्चित करेगा।

package com.home.immutable.serial; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.util.ArrayList; 
import java.util.List; 

public final class ImmutableBySerial { 

    private final int num; 
    private final String str; 
    private final ArrayList<TestObjSerial> immutableList; 

    ImmutableBySerial(int num, String str, ArrayList<TestObjSerial> list){ 
     this.num = num; 
     this.str = str; 
     this.immutableList = getDeepCloned(list); 
    } 

    public int getNum(){ 
     return num; 
    } 

    public String getStr(){ 
     return str; 
    } 

    public ArrayList<TestObjSerial> getImmutableList(){ 
     return getDeepCloned(immutableList); 
    } 

    private ArrayList<TestObjSerial> getDeepCloned(ArrayList<TestObjSerial> list){ 
     FileOutputStream fos = null; 
     ObjectOutputStream oos = null; 
     FileInputStream fis = null; 
     ObjectInputStream ois = null; 
     ArrayList<TestObjSerial> clonedObj = null; 
     try { 
      fos = new FileOutputStream(new File("temp")); 
      oos = new ObjectOutputStream(fos); 
      oos.writeObject(list); 
      fis = new FileInputStream(new File("temp")); 
      ois = new ObjectInputStream(fis); 
      clonedObj = (ArrayList<TestObjSerial>)ois.readObject(); 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       oos.close(); 
       fos.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return clonedObj; 
    } 
} 
0

आप अनिवार्य रूप से यहाँ क्या हासिल करने की कोशिश कर रहे हैं सूची अपरिवर्तनीय मुझे लगता है कि कर रही है। हालांकि जब आप सूची संदर्भ फाइनल को चिह्नित करते हैं तो इसका तात्पर्य है कि संदर्भ को इसके अलावा किसी भी अन्य सूची ऑब्जेक्ट पर इंगित नहीं किया जा सकता है।

यदि आप अंतिम (अपरिवर्तनीय) ArrayList चाहते हैं तो संग्रह वर्ग की उपयोगिता विधि संग्रह .unmodifaibleList (सूची) के लिए जाएं।

संबंधित मुद्दे