जावा में क्यों आप स्ट्रिंग को + ऑपरेटर के साथ जोड़ सकते हैं, जब स्ट्रिंग एक वर्ग है? में String.java
कोड मैं इस ऑपरेटर के लिए किसी भी कार्यान्वयन नहीं मिला। क्या यह अवधारणा वस्तु अभिविन्यास का उल्लंघन करती है?
जावा में क्यों आप स्ट्रिंग को + ऑपरेटर के साथ जोड़ सकते हैं, जब स्ट्रिंग एक वर्ग है? में String.java
कोड मैं इस ऑपरेटर के लिए किसी भी कार्यान्वयन नहीं मिला। क्या यह अवधारणा वस्तु अभिविन्यास का उल्लंघन करती है?
जवाबों:
आइए जावा में निम्नलिखित सरल भावों को देखें
int x=15;
String temp="x = "+x;
कंपाइलर आंतरिक रूप से परिवर्तित हो "x = "+x;
जाता है StringBuilder
और .append(int)
स्ट्रिंग में पूर्णांक को "जोड़ने" के लिए उपयोग करता है।
स्ट्रिंग रूपांतरण द्वारा किसी भी प्रकार को स्ट्रिंग में बदला जा सकता है।
आदिम प्रकार टी का एक मान x पहले संदर्भ मान में परिवर्तित किया जाता है जैसे कि एक उपयुक्त वर्ग उदाहरण सृजन अभिव्यक्ति (expression15.9) के तर्क के रूप में देकर:
- यदि टी बुलियन है, तो नए बुलियन (एक्स) का उपयोग करें।
- यदि T चार है, तो नए वर्ण (x) का उपयोग करें।
- यदि टी बाइट, शॉर्ट या इंट है, तो नए इंटेगर (एक्स) का उपयोग करें।
- यदि T लंबा है, तो नए Long (x) का उपयोग करें।
- यदि टी फ्लोट है, तो नए फ्लोट (x) का उपयोग करें।
- यदि T डबल है, तो नए डबल (x) का उपयोग करें।
यह संदर्भ मान स्ट्रिंग स्ट्रिंग द्वारा टाइपिंग में कनवर्ट किया जाता है।
अब केवल संदर्भ मूल्यों पर विचार करने की आवश्यकता है:
- यदि संदर्भ शून्य है, तो इसे स्ट्रिंग "null" (चार ASCII वर्ण n, u, l, l) में बदल दिया जाता है।
- अन्यथा, रूपांतरण ऐसे किया जाता है जैसे कि बिना किसी दलील के संदर्भित वस्तु के स्ट्रेचिंग विधि के आह्वान के द्वारा; लेकिन अगर स्टोस्ट्रिंग विधि को लागू करने का परिणाम शून्य है, तो इसके बजाय स्ट्रिंग "नल" का उपयोग किया जाता है।
TheString पद्धति को प्राइमर्ड क्लास ऑब्जेक्ट (.24.3.2) द्वारा परिभाषित किया गया है। कई वर्ग इसे ओवरराइड करते हैं, विशेष रूप से बूलियन, कैरेक्टर, इंटेगर, लॉन्ग, फ्लोट, डबल और स्ट्रिंग।
स्ट्रिंग रूपांतरण संदर्भ के विवरण के लिए for5.4 देखें।
स्ट्रिंग कॉनटेनटेशन का अनुकूलन: एक कार्यान्वयन एक मध्यवर्ती स्ट्रिंग स्ट्रिंग ऑब्जेक्ट को छोड़ने और फिर से बाहर निकलने से बचने के लिए एक चरण में रूपांतरण और संघनन करना चुन सकता है। बार-बार होने वाले स्ट्रिंग के संघटन के प्रदर्शन को बढ़ाने के लिए, एक जावा कंपाइलर स्ट्रिंग स्ट्रिंगर क्लास या एक समान तकनीक का उपयोग कर सकता है, जो एक अभिव्यक्ति के मूल्यांकन द्वारा बनाई गई मध्यवर्ती स्ट्रिंग ऑब्जेक्ट्स की संख्या को कम करने के लिए है।
आदिम प्रकारों के लिए, एक कार्यान्वयन एक रैपर ऑब्जेक्ट को सीधे एक आदिम प्रकार से एक स्ट्रिंग में परिवर्तित करके एक आवरण ऑब्जेक्ट के निर्माण को अनुकूलित कर सकता है।
अनुकूलित संस्करण वास्तव में एक पूर्ण लपेटा हुआ स्ट्रिंग रूपांतरण पहले नहीं करेगा।
यह संकलक द्वारा उपयोग किए गए अनुकूलित संस्करण का एक अच्छा चित्रण है, यद्यपि एक आदिम के रूपांतरण के बिना, जहां आप संकलक को चीजों को पृष्ठभूमि में स्ट्रिंगबर्ल में बदलते देख सकते हैं:
http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
यह जावा कोड:
public static void main(String[] args) {
String cip = "cip";
String ciop = "ciop";
String plus = cip + ciop;
String build = new StringBuilder(cip).append(ciop).toString();
}
इसे उत्पन्न करता है - देखें कि कैसे दो संयोजन शैली एक ही बाइटकोड को जन्म देती हैं:
L0
LINENUMBER 23 L0
LDC "cip"
ASTORE 1
L1
LINENUMBER 24 L1
LDC "ciop"
ASTORE 2
// cip + ciop
L2
LINENUMBER 25 L2
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 3
// new StringBuilder(cip).append(ciop).toString()
L3
LINENUMBER 26 L3
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 4
L4
LINENUMBER 27 L4
RETURN
ऊपर दिए गए उदाहरण को देखते हुए और दिए गए उदाहरण में स्रोत कोड के आधार पर बाइट कोड कैसे उत्पन्न होता है, आप यह नोटिस कर पाएंगे कि संकलक ने आंतरिक रूप से निम्नलिखित कथन को बदल दिया है
cip+ciop;
में
new StringBuilder(cip).append(ciop).toString();
दूसरे शब्दों में, +
स्ट्रिंग कंसट्रक्शन में ऑपरेटर अधिक क्रिया StringBuilder
मुहावरे के लिए प्रभावी रूप से आशुलिपि है ।
यह जावा संकलक सुविधा है जो +
ऑपरेटर के संचालन की जांच करती है । और ऑपरेंड के आधार पर यह बाइट कोड उत्पन्न करता है:
यह जावा कल्पना क्या कहती है :
ऑपरेटर +
-
को एडिटिव ऑपरेटर कहा जाता है। AdditiveExpression: MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - गुणात्मकExpressionयोजक संचालकों की एक ही पूर्वता होती है और वे वाक्यात्मक रूप से बाएं सहयोगी होते हैं (वे समूह बाएं से दाएं)। यदि किसी
+
ऑपरेटर के किसी भी प्रकार का प्रकार हैString
, तो ऑपरेशन स्ट्रिंग समवर्ती है।अन्यथा,
+
ऑपरेटर के प्रत्येक प्रकार का प्रकार एक प्रकार होना चाहिए जो कि एक आदिम संख्यात्मक प्रकार के लिए परिवर्तनीय (§5.1.8) है, या एक संकलन-समय त्रुटि उत्पन्न होती है।प्रत्येक मामले में, बाइनरी
-
ऑपरेटर के प्रत्येक ऑपरेंड का प्रकार एक प्रकार होना चाहिए जो कि एक आदिम संख्यात्मक प्रकार के लिए परिवर्तनीय (to5.1.8) है, या एक संकलन-समय त्रुटि उत्पन्न होती है।
कैसे स्ट्रिंग वर्ग ओवरराइड करता है + ऑपरेटर?
यह नहीं है संकलक करता है। कड़ाई से बोलते हुए, कंपाइलर स्ट्रिंग ऑपरेंड के लिए + ऑपरेटर को ओवरलोड करता है।
सबसे पहले (+) अतिभारित नहीं है
जावा लैंग्वेज स्ट्रिंग कॉन्फ्रेक्शन ऑपरेटर (+) के लिए विशेष सहायता प्रदान करता है, जिसे जावा स्ट्रिंग्स ऑब्जेक्ट्स के लिए अतिभारित किया गया है।
यदि बाएं हाथ का ऑपरेशन स्ट्रिंग है, तो यह संघनन का काम करता है।
यदि लेफ्ट हैंड साइड ऑपरेंड है तो यह इंटेगर है जो अतिरिक्त ऑपरेटर के रूप में काम करता है
int
और फिर जावा के सामान्य नियम लागू होते हैं।
जावा लैंग्वेज स्ट्रिंग कॉन्फिनेशन ऑपरेटर (+) और अन्य ऑब्जेक्ट्स को स्ट्रिंग्स में बदलने के लिए विशेष सहायता प्रदान करता है। स्ट्रिंग संघन को StringBuilder
(या StringBuffer
) वर्ग और उसकी append
विधि के माध्यम से कार्यान्वित किया जाता है ।
+
लागू होने पर ऑपरेटर का अर्थ String
भाषा द्वारा परिभाषित किया गया है, जैसा कि सभी ने पहले ही लिखा है। चूंकि आपको यह पर्याप्त रूप से समझाने योग्य नहीं लगता है, इस पर विचार करें:
इन्टस, फ्लोट्स और डबल्स सभी में अलग-अलग बाइनरी अभ्यावेदन होते हैं, और इसलिए दो फ़्लोट्स जोड़ने की तुलना में बिट्स हेरफेर के मामले में, दो इनट्स को जोड़ना एक अलग ऑपरेशन है: इनट्स के लिए आप बिट द्वारा बिट जोड़ सकते हैं, थोड़ा ले जा सकते हैं और ओवरफ़्लो की जांच कर सकते हैं; तैरने के लिए आपको अलग से मन्तीस और घातांक से निपटना चाहिए।
तो, सिद्धांत रूप में, "जोड़" वस्तुओं की प्रकृति पर निर्भर करता है "जोड़ा"। जावा स्ट्रिंग्स के साथ-साथ इन्ट्स और फ्लोट्स (लॉन्ग, डबल्स, ...) के लिए इसे परिभाषित करता है।
+
ऑपरेटर आम तौर पर एक की जगह StringBuilder
संकलन समय पर। उस मामले पर अधिक जानकारी के लिए इस उत्तर को जांचें ।
+
ऑपरेटर को प्रतिस्थापित नहीं किया गया है StringBuilder
?
+
) ऑपरेटर जावा की भाषा सुविधा है।