2015-04-14 13 views
7
import java.util.*; 
import java.lang.*; 
import java.io.*;  

class Test { 
    public static void main (String[] args) { 

     String a="hello"+"world"; //line 1 
     String b="hello"; 
     String c="world"; 
     String d=b+c; 
     String e="helloworld"; 
     System.out.println(e==a); 
     System.out.println(a==d); 
    } 
} 

उत्पादन:जावा: स्ट्रिंग शाब्दिक और + ऑपरेटर

true 

false 

इस चर्चा How does the String class override the + operator? से मैं समझ गया कि 'एक' और 'ई' एक ही स्ट्रिंग शाब्दिक वस्तु के पास भेजेगा।

किसी को भी कृपया

  1. बता सकते हैं क्यों एक और एक ही स्ट्रिंग शाब्दिक वस्तु की बात नहीं कर रहे हैं?

  2. कितने वस्तुओं लाइन में 1

उत्तर

15

JLS 4.3.3. The Class String

स्ट्रिंग संयोजन ऑपरेटर से + (§15.18.1) परोक्ष एक बनाता है: यदि कोई वस्तु अन्य उपयोग Object.equals (वस्तु ओ) इस तरह विधि के बराबर है की जाँच करने के नया स्ट्रिंग ऑब्जेक्ट जब परिणाम संकलन-समय निरंतर अभिव्यक्ति नहीं है (§15.28)।

क्योंकि एक के वस्तुतः मान "helloworld" है और घ के वस्तुतः मान b + c के संदर्भ उद्देश्य यह है कि JLS 4.3.3 ऊपर से के रूप में एक शाब्दिक नहीं है।

से JLS 3.10.5 String Literals

एक स्ट्रिंग शाब्दिक डबल उद्धरण में संलग्न शून्य या अधिक वर्ण होते हैं।

    :

15.28. Constant Expressions

एक संकलन समय निरंतर अभिव्यक्ति से एक अभिव्यक्ति है कि अचानक पूरा नहीं करता है और केवल का उपयोग कर बना है निम्नलिखित आदिम प्रकार या एक स्ट्रिंग के एक मूल्य को संकेतित करते है

  • प्राचीन प्रकार के अक्षर और प्रकार के अक्षर स्ट्रिंग (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10।5)
  • आप बनाने के लिए System.out.println(a==d);सच उपयोग final कीवर्ड कोड नीचे देखें चाहते हैं:

    String a="hello"+"world"; //line 1 
        final String b="hello"; // now b is a literal 
        final String c="world";// now c is a literal 
        String d=b+c; 
        String e="helloworld"; 
        System.out.println(e==a); 
        System.out.println(a==d);// now it will be true because both are literals. 
    

    टिप्पणी के लिए उत्तर:
    कितने वस्तुओं लाइन में निर्माण कर रहे थे 1: उत्तर 3
    स्ट्रिंग ए = "हैलो" + "दुनिया";

    1 शाब्दिक वस्तु hello
    2 शाब्दिक वस्तु world
    3 शाब्दिक वस्तु "hello"+"world" == "helloworld"

    +0

    डी 'c + b' का एक संदर्भ वस्तु है .. और नहीं 'ए + बी' – Rishabh

    +0

    उत्तर अपडेट किया गया। –

    +0

    @ सुमित मुझे लाइन 1 के आंतरिक प्रतिनिधित्व में एक और संदेह है। क्या लाइन 1 का आंतरिक प्रतिनिधित्व नया स्ट्रिंगबिल्डर ("हैलो") है। संलग्न करें ("दुनिया")। ToString()? – nantitv

    2

    == संकेत चेकों निर्माण कर रहे थे, तो चर के लिए संदर्भ एक ही हैं।

    e.equals(a); 
    
    1

    == ऑपरेटर चेकों संदर्भ समानता, समानता आपत्ति नहीं। आपके उदाहरण में दो String सामग्री "helloworld" के साथ उदाहरण बनाए गए हैं। चर a और e एक ही उदाहरण देखें (नीचे देखें), जबकि a और d नहीं। स्ट्रिंग समानता equals() विधि के साथ जांच की जा सकती है, जो a.equals(d) सत्य है।

    कारण a और e एक ही उदाहरण का संदर्भ है कि स्ट्रिंग स्थिरांक इंटर्न किए गए हैं। हर बार एक स्ट्रिंग स्थिर, जैसे "helloworld", का सामना करना पड़ता है, यह जांच की जाती है कि अगर ऐसा स्थिरता पहले से सामना कर रहा था, और यदि उसके पास है, तो नया String उदाहरण एक नया बनाने के बजाय वापस कर दिया गया है। हालांकि "hello" + "world" स्ट्रिंग स्थिरांक की तरह दिखता नहीं है, इसे जावा कंपाइलर द्वारा स्ट्रिंग स्थिरांक के लिए अनुकूलित किया गया है, और इसलिए इसे e जैसा प्रशिक्षित किया गया है, यही कारण है कि a == e सत्य है। कॉन्सस्ट्रास्ट में, b + c को स्थिर करने के लिए अनुकूलित नहीं किया गया है, यही कारण है कि a == d गलत है (हालांकि, a.equals(d) सत्य होगा)।

    0

    == ऑपरेटर जांचता है कि क्या दो वस्तुएं स्मृति में एक ही स्थान को संदर्भित करती हैं।

    a = "hello" + "world;" शाब्दिक "helloworld" और e="helloworld" का मूल्यांकन किया जाता है। वे एक ही स्मृति स्थान का संदर्भ लें। इसलिए अभिव्यक्ति e==a सत्य का मूल्यांकन करती है।

    अभिव्यक्ति d=b+c भी "helloworld" का मूल्यांकन करती है लेकिन यह परिणाम एक अलग स्थान पर संग्रहीत होता है। यह एक ही वस्तु का संदर्भ नहीं देता है। इसलिए अभिव्यक्ति a==d झूठी का मूल्यांकन करती है।

    a.equals(d) का उपयोग करके आउटपुट सही होगा क्योंकि equals() 2 ऑब्जेक्ट्स की सामग्री की जांच करता है।

    1

    1) ऐसा इसलिए है क्योंकि स्ट्रिंग ऑब्जेक्ट्स अपरिवर्तनीय हैं। एक बार जब आप स्ट्रिंग ऑब्जेक्ट बनाते हैं और इसे मान देते हैं, तो उसके पास वही मान हमेशा के लिए होता है जिसे बदला नहीं जा सकता है। इस प्रकार जब आप इसके साथ कोई संचालन करते हैं (उदाहरण के लिए शामिल हो) तो हमेशा एक नया स्ट्रिंग ऑब्जेक्ट बनाया गया है।

    ढेर में इसका एक विशेष हिस्सा है जो स्ट्रिंग स्थिरांक के लिए पूल के रूप में कार्य करता है। यदि कंपाइलर स्ट्रिंग शाब्दिक से मुकाबला करता है, तो यह पहले स्मृति के इस भाग को देखता है चाहे समान वस्तु (स्ट्रिंग) पहले से मौजूद है। यदि ऐसा होता है, तो यह एक नया निर्माण करने के बजाय इस पहले से मौजूद ऑब्जेक्ट (स्ट्रिंग) का संदर्भ निर्दिष्ट करता है। (यह कारण है कि स्ट्रिंग रों अपरिवर्तनीय हैं, इसलिए कोई भी। इसे बदल सकते हैं क्योंकि अगर कई संदर्भ इस स्ट्रिंग को इंगित होता है और उनमें से एक अपने मूल्य बदल जाएगा, यह एक गड़बड़ पैदा करेगा।)

    अब देखते हैं कि इस कोड स्निपेट में क्या हो रहा है और एक बार में अपने दोनों सवालों के जवाब खोजने का प्रयास करें।

    (1) String a="hello"+"world"; //line 1 
    (2) String b="hello"; // now b is a literal 
    (3) String c="world"; 
    (4) String d=b+c; 
    (5) String e="helloworld"; 
    (6) System.out.println(e==a); 
    (7) System.out.println(a==d); 
    

    (1) पहले वहाँ एक संदर्भ मूल्य एक कि स्ट्रिंग टाइप करने के लिए कहते हैं बनाया जाता है। इसके बाद पहले उल्लेख किए गए ढेर में इस विशेष पूल में शाब्दिक "हैलो" बनाया गया है (पहली स्ट्रिंग ऑब्जेक्ट)। फिर पूल में शाब्दिक "दुनिया" बनाया गया है (द्वितीय स्ट्रिंग ऑब्जेक्ट)। फिर, चूंकि स्ट्रिंग्स अपरिवर्तनीय हैं, इस पूल में "helloworld" में एक और शाब्दिक बनाया गया है और इसे इस संदर्भ चर (तृतीय स्ट्रिंग ऑब्जेक्ट - यह आपके प्रश्न का उत्तर है। 2)।

    (2) पूल में "हैलो" और "दुनिया" बनाए गए (1) पूल में बनाए गए थे और किसी भी संदर्भ मूल्य को असाइन नहीं किए गए थे, लेकिन वे इस पूल में मौजूद हैं। इस पंक्ति में स्ट्रिंग बी प्रकार का संदर्भ चर है और इसे पूल में मौजूद इस शाब्दिक "हैलो" को असाइन किया गया है।

    (3) (2)

    (4) बनाया गया संदर्भ प्रकार स्ट्रिंग का मूल्य के रूप में ही। यद्यपि पहले से ही स्ट्रिंग मूल्य "helloworld" के साथ इस विशेष ढेर भाग (पूल) में शाब्दिक है, मूल्य "helloworld" के साथ नई स्ट्रिंग ऑब्जेक्ट को ढेर में बनाया गया है - जिसका अर्थ है ढेर के गैर-पूल हिस्से में। इसलिए आपके पास स्ट्रिंग के दो अलग-अलग ऑब्जेक्ट्स हैं, "helloworld" (पूल में एक और दूसरा ढेर के गैर-पूल हिस्से में) के साथ। यदि आप अब == ऑपरेटर संदर्भ मानों की तुलना और डी से तुलना करते हैं, तो दोनों अलग-अलग ऑब्जेक्ट्स को इंगित करते हैं (हालांकि समान मान के साथ, विधि विधि बराबर सच हो जाएगी)।

    (5) स्ट्रिंग प्रकार के संदर्भ मूल्य बनाया गया। ढेर के पूल हिस्से में पहले से ही एक स्ट्रिंग "helloworld" है (हमने इसे (1) में बनाया है और इसे संदर्भ चर पर इंगित किया है) इसलिए संदर्भ चर इस ऑब्जेक्ट को असाइन किया गया है। और के समान स्थान पर इंगित करता है। इसलिए यदि आप एक == ई संदर्भों की तुलना करते हैं तो आप सच हो जाते हैं।एक ही विधि के लिए किया जाएगा के बराबर होती है

    (6) और (7) पिछले अंक में विस्तार से बताया गया

    TLDR:

    1) क्योंकि यह एक ही वस्तु

    2) 3

    नहीं है
    संबंधित मुद्दे