2011-12-19 14 views
52

OpenJDK में, विधि के लिए:Double.valueof javadoc क्यों कहता है कि यह मूल्यों को कैश करता है, जब ऐसा नहीं होता है?

public static Double valueOf(double d) 

जावाडोक का कहना है:

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

public static Double valueOf(double d) { 
    return new Double(d); 
} 

कैश एक झूठ है:

यहाँ वास्तविक कोड है! यहाँ क्या चल रहा है?

+31

प्रलेखन हमेशा गलत है। उसे याद रखो। –

+5

आप किसी भी तरह से कोड कहां लेते हैं? OpenJDK6? OpenJDK7? अपाचे सद्भावना? जीएनयू कक्षापाथ? – scravy

+0

@scravy मैं ओपनजेडीके 7 देख रहा हूं लेकिन आधिकारिक सूर्य रिलीज में वर्षों से यह कोड नहीं बदला है। –

उत्तर

54

विधि कई प्रकार के लिए मौजूद है: Integer, Long, BigDecimal और दूसरों और प्रलेखन हमेशा एक ही है: कुछ परिस्थितियों (जो परिभाषित नहीं कर रहे हैं) के तहत विधि ही परिणाम लौट सकते हैं।

AFAIK, कैशिंग केवल पूर्णांक प्रकार के लिए लागू किया गया है और यह -128 और 127 (सबसे सामान्य मान) के बीच मूल्यों के लिए कैश्ड उदाहरणों देता है। BigDecimal के लिए, कैश वर्तमान में जावा की 10

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

जावा, उदाहरण के लिए, जब autoboxing के लिए कोड जनरेट इस API का उपयोग करता।

6

एपीआई के डिजाइनर शायद वैकल्पिक कार्यान्वयन को सीमित नहीं करना चाहते थे। वे Double कक्षा में कैशिंग जोड़ने के लिए स्वतंत्र हैं।

29

एपीआई डॉक के साथ गलत कुछ भी नहीं है:

इस विधि संभावना उपज के लिए है ...

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

+4

+1। आईएमएचओ, मुख्य बिंदु यह है कि ओपी "* * * वास्तविक कोड" लिखता है, लेकिन वह जो आपूर्ति करता है वह केवल * एक * कार्यान्वयन है। अन्य कार्यान्वयन अन्य प्लेटफॉर्म के लिए मौजूद और कर सकते हैं। (विशेष रूप से, यह मुझे फर्मवेयर कार्यान्वयन में एक अंतर देखने के लिए आश्चर्यचकित नहीं करेगा।) – ruakh

+0

@ruakh मैंने सोचा होगा कि एक वैकल्पिक कार्यान्वयन वैकल्पिक जावाडोक के साथ भी आएगा। कोड और जावाडोक एक साथ जाते हैं, यह उच्च स्तरीय विनिर्देश दस्तावेज़ नहीं माना जाता है। वह कोड से संबंधित नहीं होगा। –

+7

जावा का जावडोक * कक्षाएं * विनिर्देश हैं, क्योंकि अन्य वे ओरेकल के अलावा अन्य विक्रेता हैं जो जावा कार्यान्वयन लिखते हैं और उन्हें इन सभी वर्गों के लिए समान कार्यक्षमता प्रदान करनी होती है। –

2

ये valueOf() तरीकों प्रयोजन के लिए हर सांख्यिक प्रकार में मौजूद कैशिंग समर्थन करने के लिए। वास्तव में, डबल के लिए यह किसी भी कैश लेकिन Integer और Long के लिए उपयोग नहीं करता।

12

जावा 1.5+ से, JVM/JIT Integer रों -127 127 की कैशिंग की गारंटी देता है तो यही कारण है कि Integer के लिए पसंदीदा दृष्टिकोण valueOf उपयोग करने के लिए है। आप आम तौर पर double के लिए निर्माता का उपयोग कर क्योंकि तब JIT वह उचित देखता है अपने कोड का अनुकूलन करने में सक्षम है से अधिक valueOf उपयोग करना चाहिए।उदाहरण के लिए, निम्नलिखित पाश पर विचार करें:

for (Object o: objectList) { 
    o.setValue(Double.valueOf(0.0)); 
} 

इस उदाहरण में, JIT डबल वस्तु precalculate और लूप के प्रत्येक यात्रा पर एक ही मूल्य को पुन: असाइन है, जबकि आप new Double(0.0); उपयोग करने के लिए थे अगर यह सक्षम नहीं होगा कर सकते हैं ऐसा करने के लिए।

+0

+1 कैशिंग के उपयोग-केस को हाइलाइट करने के लिए। – Luke

+2

बधाई हो, अब आपके पास 2013 प्रतिनिधि हैं, नया साल मुबारक हो 2013 :) –

+0

@ मोहम्मदशेखर सावन धन्यवाद - जिसने मेरा दिन बनाया :) – Deco

2

याद रखें कि एम्बेडेड डिवाइस (ज्यादातर) के लिए कोड आकार को कम करने के लिए जेवीएम बनाया गया था - यह एक सेट-टॉप बॉक्स ऑपरेटिंग सिस्टम है। मैंने कुछ एम्बेडेड जावा प्लेटफार्मों पर काम किया है और उन पर "मूल्य" का मूल्य अधिक स्पष्ट होगा, यह कुछ मामलों में काफी जगह बचाएगा।

अधिकतर विधि मौजूद है क्योंकि "नया" कभी भी कैश किए गए उदाहरणों का उपयोग नहीं कर सकता है। मूल्य कैश किए गए उदाहरणों का उपयोग करने के लिए लागू किया जा सकता है (अन्यथा आप हमेशा नए का उपयोग करेंगे) और संभवतः समय बचाने के लिए साबित होता है।

यदि वे (या आपने) उस विधि को वास्तव में कैश मानों के साथ बदल दिया है तो आपके सभी कोड को उस परिवर्तन का लाभ मिलेगा, लेकिन "valueOf" जैसी विधि प्रदान करके तैयार किए बिना यह कभी नहीं हो सकता है (ठीक है, व्यावहारिक रूप से कभी नहीं - आप "नए" रिटर्न कैश किए गए मानों के लिए कंपाइलर/बाइटकोड निष्पादक को ट्विक कर सकते हैं लेकिन मुझे लगता है कि कुछ अनुबंध तोड़ेंगे)

तो कैश वास्तव में झूठ नहीं है, केवल दिमाग की स्थिति है।

+2

क्या आप जेवीएम के कारण के बारे में बयान का संदर्भ दे सकते हैं?Autoboxing का समर्थन करने के लिए valueOf विधियां नई हैं। इनके लिए कभी भी रचनाकार नहीं होना चाहिए, यह विशेष रूप से बूलियन के लिए जाता है। – stolsvik

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