2010-06-04 17 views
64

मैं अपने कोड क्लीनर को बनाने के लिए Sonar का उपयोग कर रहा था, और यह इंगित करता है कि Integer.valueOf(1) के बजाय मैं new Integer(1) का उपयोग कर रहा हूं। क्योंकि ऐसा लगता है कि valueOf एक नई वस्तु को तुरंत चालू नहीं करता है, इसलिए अधिक स्मृति-अनुकूल है। valueOf कैसे एक नई वस्तु को चालू नहीं कर सकता है? यह कैसे काम करता है? क्या यह सभी पूर्णांक के लिए सच है?नया इंटीजर बनाम मूल्य

+13

नोट 127 की एक कैश बनाता है: यदि आप autoboxing उपयोग करें, यह पूर्णांक उपयोग करता है। आपके लिए मूल्य (int)। –

उत्तर

66

Integer.valueO मूल्यों के लिए कैश लागू करता है -128 से +127। जावा भाषा विशिष्टता, खंड 5.1.7 का अंतिम पैराग्राफ देखें, जो मुक्केबाजी के लिए आवश्यकताओं को समझाता है (आमतौर पर .valueOf विधियों के संदर्भ में लागू)।

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

+0

मुझे पता है, यह कहीं भी अनबॉक्सिंग में था, लेकिन मुझे अनुभाग मिल सकता था। धन्यवाद – LB40

+1

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

+21

बस पूर्णता के लिए, यह भी ध्यान दें कि सूर्य वीएम पर, कैश का अधिकतम मूल्य उपयोगकर्ता-कॉन्फ़िगर करने योग्य है '-XX: AutoBoxCacheMax = ...' –

26

JavaDoc से:

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

ValueOf आम तौर पर autoboxing के लिए इस्तेमाल किया है और इसलिए (जब autoboxing के लिए प्रयोग) autoboxing विनिर्देश पालन करने के लिए कम से कम मूल्यों पर -128 से 127 तक कैश है।

यहां सूर्य JVM 1.5 के लिए valueOf कार्यान्वयन है। कैश शुरू करने के तरीके को देखने के लिए पूरी कक्षा पर एक नज़र डालें।

public static Integer valueOf(int i) { 
    final int offset = 128; 
    if (i >= -128 && i <= 127) { // must cache 
     return IntegerCache.cache[i + offset]; 
    } 
    return new Integer(i); 
} 
2

वे तुम्हें valueOf()new Integer() के बजाय का उपयोग करने पर जोर दे रहे हैं, ताकि विधि valueOf() यह आप के लिए करता है, और इस मामले में मूल्य कैश यदि आप भविष्य में एक ही नंबर प्राप्त करना चाहते हैं। उस स्थिति में, विधि नए इंटीजर को चालू नहीं करेगी, लेकिन आपको कैश किए गए एक को देगा, जो नए इंटीजर की 'सृजन' को बहुत तेज़ और मेमोरी अनुकूल प्रक्रिया बना देगा ..

इस तरह आप स्वयं को बहुत से कारण बना सकते हैं समस्याएं यदि आप अनुभवहीन जावा प्रोग्रामर हैं क्योंकि आप निष्कर्ष निकाल देंगे कि Integer.valueOf(342)==Integer.valueOf(342), क्योंकि आप दो इंटीग्रियों के लिए एक ही सूचक हो सकते हैं (या नहीं), और शायद आप इसे एक तरह से अभ्यास करेंगे, मान लीजिए, आपने सी # में सीखा है, ताकि आपको समय-समय पर बग दिखाएगा, और आपको नहीं पता होगा कि & कहां से आए थे ...

2

java.lang.Integer स्रोत कोड से। इंटीजर कैश विन्यास योग्य है। सूर्य के अलावा इंटीजर कैश आकार को कॉन्फ़िगर करने के लिए हमें स्रोत कोड के अनुसार सिस्टम प्रॉपर्टी java.lang.Integer.IntegerCache.high का उपयोग करने की आवश्यकता है।

/** 
* Cache to support the object identity semantics of autoboxing for values between 
* -128 and 127 (inclusive) as required by JLS. 
* 
* The cache is initialized on first usage. During VM initialization the 
* getAndRemoveCacheProperties method may be used to get and remove any system 
* properites that configure the cache size. At this time, the size of the 
* cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>. 
*/ 

// value of java.lang.Integer.IntegerCache.high property (obtained during VM init) 
private static String integerCacheHighPropValue; 

static void getAndRemoveCacheProperties() { 
    if (!sun.misc.VM.isBooted()) { 
     Properties props = System.getProperties(); 
     integerCacheHighPropValue = 
      (String)props.remove("java.lang.Integer.IntegerCache.high"); 
     if (integerCacheHighPropValue != null) 
      System.setProperties(props); // remove from system props 
    } 
} 

private static class IntegerCache { 
    static final int high; 
    static final Integer cache[]; 

    static { 
     final int low = -128; 

     // high value may be configured by property 
     int h = 127; 
     if (integerCacheHighPropValue != null) { 
      // Use Long.decode here to avoid invoking methods that 
      // require Integer's autoboxing cache to be initialized 
      int i = Long.decode(integerCacheHighPropValue).intValue(); 
      i = Math.max(i, 127); 
      // Maximum array size is Integer.MAX_VALUE 
      h = Math.min(i, Integer.MAX_VALUE - -low); 
     } 
     high = h; 

     cache = new Integer[(high - low) + 1]; 
     int j = low; 
     for(int k = 0; k < cache.length; k++) 
      cache[k] = new Integer(j++); 
    } 

    private IntegerCache() {} 
} 

java.lang.Short, java.lang.Byte और java.lang.Long से -128

private static class LongCache { 
    private LongCache() { 
    } 

    static final Long cache[] = new Long[-(-128) + 127 + 1]; 

    static { 
     for (int i = 0; i < cache.length; i++) 
      cache[i] = new Long(i - 128); 
    } 
} 

private static class ShortCache { 
    private ShortCache() { 
    } 

    static final Short cache[] = new Short[-(-128) + 127 + 1]; 

    static { 
     for (int i = 0; i < cache.length; i++) 
      cache[i] = new Short((short) (i - 128)); 
    } 
} 

private static class ByteCache { 
    private ByteCache() { 
    } 

    static final Byte cache[] = new Byte[-(-128) + 127 + 1]; 

    static { 
     for (int i = 0; i < cache.length; i++) 
      cache[i] = new Byte((byte) (i - 128)); 
    } 
} 
संबंधित मुद्दे