हमें स्ट्रिंग के शाब्दिक अर्थों पर स्ट्रिंग की आंतरिक पद्धति का उपयोग कब करना चाहिए


187

स्ट्रिंग # इंटर्न () के अनुसार , internयदि स्ट्रिंग स्ट्रिंग पूल में पाई जाती है, तो स्ट्रिंग को स्ट्रिंग पूल से वापस करने का तरीका माना जाता है, अन्यथा स्ट्रिंग पूल में एक नया स्ट्रिंग ऑब्जेक्ट जोड़ा जाएगा और इस स्ट्रिंग का संदर्भ वापस आ गया है।

तो मैंने यह कोशिश की:

String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();

if ( s1 == s2 ){
    System.out.println("s1 and s2 are same");  // 1.
}

if ( s1 == s3 ){
    System.out.println("s1 and s3 are same" );  // 2.
}

मैं उम्मीद कर रहा था कि s1 and s3 are sames3 के रूप में मुद्रित किया s1 and s2 are sameजाएगा , और मुद्रित नहीं किया जाएगा। लेकिन परिणाम है: दोनों लाइनें मुद्रित हैं। तो इसका मतलब है, डिफ़ॉल्ट रूप से स्ट्रिंग स्थिरांक को नजरबंद कर दिया गया है। लेकिन अगर ऐसा है, तो हमें internविधि की आवश्यकता क्यों है ? दूसरे शब्दों में, हमें इस पद्धति का उपयोग कब करना चाहिए?


14
आपके द्वारा जोड़ा गया Javadoc यह भी बताता है कि "सभी शाब्दिक तार और स्ट्रिंग-मूल्यवान स्थिर अभिव्यक्तियों को नजरबंद किया गया है।"
Jorn


1
एक सटीक डुप्लिकेट नहीं ..
Bozho

1
@ जोर्न: यह सही है। तो हमारे पास internसार्वजनिक पद्धति क्यों है । क्या हमारे पास internनिजी पद्धति के रूप में नहीं होना चाहिए , ताकि किसी के पास इसका उपयोग न हो। या इस विधि का कोई उद्देश्य है?
राकेश जुयाल

2
@ राकेशजुयाल: इंटर्न विधि को एक स्ट्रिंग प्रकार पर परिभाषित किया गया है जो स्ट्रिंग शाब्दिक या चर हो सकता है। यदि विधि निजी थी, तो आप एक चर को कैसे पूरा करेंगे?
बॉबीलेक्स

जवाबों:


230

जावा स्वचालित रूप से स्ट्रिंग शाब्दिक इंटर्न करता है। इसका मतलब यह है कि कई मामलों में, == ऑपरेटर स्ट्रिंग्स के लिए उसी तरह से काम करता दिखाई देता है, जैसे कि यह किलों या अन्य आदिम मूल्यों के लिए करता है।

चूंकि स्ट्रिंग स्ट्रिंग के लिए इंटर्निंग स्वचालित है, इसलिए इस intern()विधि का उपयोग स्ट्रिंग्स के निर्माण के लिए किया जाना हैnew String()

अपने उदाहरण का उपयोग करना:

String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
String s4 = new String("Rakesh");
String s5 = new String("Rakesh").intern();

if ( s1 == s2 ){
    System.out.println("s1 and s2 are same");  // 1.
}

if ( s1 == s3 ){
    System.out.println("s1 and s3 are same" );  // 2.
}

if ( s1 == s4 ){
    System.out.println("s1 and s4 are same" );  // 3.
}

if ( s1 == s5 ){
    System.out.println("s1 and s5 are same" );  // 4.
}

वापस होगा:

s1 and s2 are same
s1 and s3 are same
s1 and s5 are same

s4चर के अलावा सभी मामलों में , जिसके लिए एक मान स्पष्ट रूप से newऑपरेटर का उपयोग करके बनाया गया था और जहां internविधि का उपयोग इसके परिणाम पर नहीं किया गया था, यह एक एकल अपरिवर्तनीय उदाहरण है जिसे JVM के स्ट्रिंग स्थिर पूल में लौटाया जा रहा है ।

अधिक जानकारी के लिए JavaTechniques "String Equality and Interning" का संदर्भ लें ।


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

जावा में नया (मैं C # .NET दुनिया से हूं) और मैं कभी-कभी एक जावा विरासत परियोजना में देखता हूं "" .intern () तो अगर मैं इसे सही ढंग से समझता हूं कि यह खाली तारों के लिए भी "बकवास" है।
hfrmobile

4
@ मिगुएल नीस स्पष्टीकरण, मेरा सवाल यह है कि आप यहां उदाहरण में कैसे ऑब्जेक्ट बना सकते हैं। यहाँ मेरे धारणा है: String s1 = "Rakesh"; पहला OB1 String s4 = new String("Rakesh");(S2, S3, S5) संदर्भ एक ही वस्तु (OB1) 'स्ट्रिंग पूल' तो में बनाया मैं कह सकता हूँ कि दूसरा OB2 तो बाकी .intern()नई वस्तु बनाने के लिए विधि रोकें के लिए इस्तेमाल करता है, तो एक ही स्ट्रिंग में उपलब्ध string poolहैं मेरी धारणा गलत है इसलिए मुझे दिशा दें।
हाइब्रिस हेल्प

1
JavaTechniques लिंक टूट गया है
SJuan76


20

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

नजरबंद स्ट्रिंग्स का एक और छोटा लाभ यह है कि स्ट्रिंग्स की ==तुलना करने के लिए (सफलतापूर्वक!) उपयोग किया जा सकता है यदि सभी शामिल स्ट्रिंग्स को नजरबंद करने की गारंटी दी जाती है। लीनर सिंटैक्स के अलावा, यह एक प्रदर्शन वृद्धि भी है। लेकिन जैसा कि दूसरों ने बताया है, इस तरह से प्रोग्रामिंग त्रुटियों को शुरू करने का एक बड़ा जोखिम है, इसलिए इसे केवल अंतिम उपाय के एक नापने के उपाय के रूप में किया जाना चाहिए।

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


@ The downside is that interning a String takes more time than simply throwing it on the heap, and that the space for interned Strings may be limitedयहां तक ​​कि अगर आप स्ट्रिंग निरंतर के लिए आंतरिक विधि का उपयोग नहीं करते हैं तो यह स्वचालित रूप से इंटर्न किया जाएगा।
राकेश जुयाल

2
@ राकेश: किसी भी वर्ग में आमतौर पर कई स्ट्रिंग स्थिरांक नहीं होते हैं, इसलिए यह स्थिरांक के लिए जगह / समय की समस्या नहीं है।
डेविड रॉड्रिग्ज - ड्रिबेक्स

हां, राकेश की टिप्पणी लागू नहीं होती क्योंकि इंटर्निंग स्ट्रिंग्स केवल (स्पष्ट रूप से) स्ट्रिंग्स के साथ किया जाता है जो किसी भी तरह "उत्पन्न" होते हैं, यह आंतरिक हेरफेर या डेटाबेस या इस तरह से पुनर्प्राप्त करके हो। स्थिरांक के साथ हमारे पास कोई विकल्प नहीं है।
कार्ल स्मोत्रिकज़

2
+1। मुझे लगता है कि जब इंटर्न समझ में आता है तो यह एक अच्छा उदाहरण है। मैं ==हालांकि तार के लिए सहमत नहीं हूँ ।
अलेक्जेंडर पोगरेबनेक

1
जावा 7 के बाद से "स्ट्रिंग पूल" को हीप स्पेस में लागू किया जाता है, इसलिए इसे स्टोरिंग इंटर्न्स, कचरा संग्रहण के सभी फायदे मिलते हैं और इसका आकार सीमित नहीं है, इसे ढेर के आकार तक बढ़ाया जा सकता है। (आपको कभी भी इसकी आवश्यकता नहीं होगी। मेमोरी फॉर स्ट्रिंग्स)
अनिल उत्तानी

15

मैं अपने 2 सेंट जोड़ना चाहता हूँ ==इंटर्निंग स्ट्रिंग्स के साथ उपयोग करने पर ।

पहली बात String.equalsकरता है this==object

इसलिए हालांकि कुछ मिनिस्क्यूल परफॉर्मेंस गेन (आप एक तरीका नहीं कह रहे हैं), मेंटेनर के दृष्टिकोण से उपयोग ==करना एक बुरा सपना है, क्योंकि कुछ नजरबंद स्ट्रिंग्स में गैर-इंटर्न बनने की प्रवृत्ति होती है।

इसलिए मैं सुझाव देता हूं कि ==नजरबंद स्ट्रिंग्स के लिए विशेष मामले पर भरोसा न करें , लेकिन हमेशा equalsगोस्लिंग का उपयोग करें ।

संपादित करें: इंटर्न गैर-प्रशिक्षु बन रहा है:

V1.0
public class MyClass
{
  private String reference_val;

  ...

  private boolean hasReferenceVal ( final String[] strings )
  {
    for ( String s : strings )
    {
      if ( s == reference_val )
      {
        return true;
      }
    }

    return false;
  }

  private void makeCall ( )
  {
     final String[] interned_strings =  { ... init with interned values ... };

     if ( hasReference( interned_strings ) )
     {
        ...
     }
  }
}

संस्करण 2.0 में अनुरक्षक ने hasReferenceValसार्वजनिक करने का फैसला किया , बहुत विस्तार में जाने के बिना कि यह आंतरिक तार की एक सरणी की उम्मीद करता है।

V2.0
public class MyClass
{
  private String reference_val;

  ...

  public boolean hasReferenceVal ( final String[] strings )
  {
    for ( String s : strings )
    {
      if ( s == reference_val )
      {
        return true;
      }
    }

    return false;
  }

  private void makeCall ( )
  {
     final String[] interned_strings =  { ... init with interned values ... };

     if ( hasReference( interned_strings ) )
     {
        ...
     }
  }
}

अब आपके पास एक बग है, जिसे खोजना बहुत कठिन हो सकता है, क्योंकि अधिकांश मामलों में सरणी में शाब्दिक मूल्य होते हैं, और कभी-कभी गैर-शाब्दिक स्ट्रिंग का उपयोग किया जाता है। तो equalsबजाय इस्तेमाल किया गया ==तो hasReferenceValअब भी होता है काम जारी है। एक बार फिर, प्रदर्शन लाभ न्यूनतम है, लेकिन रखरखाव की लागत अधिक है।


"कुछ आंतरिक तार गैर-आंतरिक हो जाते हैं।" वाह, यह अजीब होगा। क्या आप कृपया एक संदर्भ का हवाला दे सकते हैं?
कार्ल स्मोत्रिकज

2
ठीक है, मुझे लगा कि आप स्ट्रिंग्स का जिक्र कर रहे हैं, वास्तव में इंटरनैशनल पूल से बाहर भटक रहे हैं और जेवीएम में जादू के लिए ढेर धन्यवाद। आप जो कह रहे हैं, वह यह है कि == प्रोग्रामर त्रुटियों के कुछ वर्गों को अधिक संभावना बनाता है।
कार्ल स्मोत्रिकज़ 12

"तो मैं सुझाव देता हूं कि आंतरिक तारों के लिए == के विशेष मामले पर भरोसा न करें, लेकिन हमेशा गोसलिंग के रूप में बराबरी का उपयोग करें।" क्या आपको यह बताते हुए गोस्लिंग से कोई सीधा उद्धरण या टिप्पणी मिली है? अगर ऐसा है तो उसने भाषा में इंटर्न () और == का उपयोग करने की भी जहमत क्यों उठाई?

1
इंटर्न सीधे तुलना (==) के लिए अच्छा नहीं है, भले ही यह काम करता है अगर दोनों तार इंटर्न हैं। उपयोग की गई कुल मेमोरी को कम करना बहुत अच्छा है: जब एक ही तार 1 से अधिक जगह पर उपयोग किया जाता है।
tgkprog

12

स्ट्रिंग शाब्दिक और स्थिरांक डिफ़ॉल्ट रूप से नजरबंद हैं। यह है, "foo" == "foo"(स्ट्रिंग शाब्दिकों द्वारा घोषित), लेकिन new String("foo") != new String("foo")


4
तो, सवाल है जब हम का उपयोग करना चाहिए है intern,
राकेश जुयाल

कि कल से उनमें से कुछ के stackoverflow.com/questions/1833581/when-to-use-intern , और कई अन्य सवालों के लिए कहा गया था ।
बूझो

मुझे बताएं कि क्या इस कथन के लिए मेरी समझ:, String literals and constants are interned by defaultसही है। new String("foo")-> यहां, एक स्ट्रिंग शाब्दिक "फू" स्ट्रींग पूल में और एक ढेर में बनाया गया है, इसलिए कुल 2 ऑब्जेक्ट बनाए गए हैं।
dkb

8

जावा स्ट्रिंग इंटर्न जानें - एक बार सभी के लिए

जावा में तार डिजाइन द्वारा अपरिवर्तनीय वस्तुएं हैं। इसलिए, समान मूल्य वाले दो स्ट्रिंग ऑब्जेक्ट भी डिफ़ॉल्ट रूप से अलग-अलग ऑब्जेक्ट होंगे। हालाँकि, यदि हम मेमोरी को सहेजना चाहते हैं, तो हम स्ट्रिंग इंटर्न नामक एक अवधारणा द्वारा उसी मेमोरी का उपयोग करने का संकेत दे सकते हैं।

नीचे दिए गए नियम आपको स्पष्ट शब्दों में अवधारणा को समझने में मदद करेंगे:

  1. स्ट्रिंग वर्ग एक आंतरिक-पूल रखता है जो शुरू में खाली होता है। इस पूल में केवल विशिष्ट मान वाले स्ट्रिंग ऑब्जेक्ट्स को रखने की गारंटी होनी चाहिए।
  2. समान मूल्य वाले सभी स्ट्रिंग शाब्दिक को समान स्मृति-स्थान ऑब्जेक्ट माना जाना चाहिए क्योंकि उनके पास अन्यथा कोई भेद की धारणा नहीं है। इसलिए, समान मूल्य वाले ऐसे सभी शाब्दिक इंटर्न-पूल में एकल प्रविष्टि करेंगे और समान मेमोरी स्थान को संदर्भित करेंगे।
  3. दो या दो से अधिक शाब्दिक अर्थों का एक शाब्दिक अर्थ भी है। (इसलिए नियम # 2 उनके लिए लागू होगा)
  4. प्रत्येक स्ट्रिंग को ऑब्जेक्ट के रूप में बनाया जाता है (अर्थात शाब्दिक के अलावा किसी भी अन्य विधि द्वारा) अलग-अलग मेमोरी लोकेशन होंगे और इंटर्न-पूल में कोई प्रविष्टि नहीं करेगा
  5. गैर-शाब्दिक के साथ शाब्दिक का एक गैर-शाब्दिक बनाना होगा। इस प्रकार, परिणामी वस्तु में एक नया मेमोरी लोकेशन होगा और इंटर्न-पूल में एक प्रविष्टि नहीं करेगा।
  6. एक स्ट्रिंग ऑब्जेक्ट पर इंटर्न विधि को लागू करना, या तो एक नई ऑब्जेक्ट बनाता है जो इंटर्न-पूल में प्रवेश करता है या पूल से एक मौजूदा ऑब्जेक्ट को वापस करता है जो समान मूल्य है। किसी भी वस्तु पर मंगलाचरण जो कि आंतरिक-पूल में नहीं है, वह वस्तु को पूल में नहीं ले जाता है। यह एक और वस्तु बनाता है जो पूल में प्रवेश करता है।

उदाहरण:

String s1=new String (“abc”);
String s2=new String (“abc”);
If (s1==s2)  //would return false  by rule #4
If (“abc == a”+”bc )  //would return true by rules #2 and #3
If (“abc == s1 )  //would return false  by rules #1,2 and #4
If (“abc == s1.intern() )  //would return true  by rules #1,2,4 and #6
If ( s1 == s2.intern() )      //wound return false by rules #1,4, and #6

नोट: स्ट्रिंग इंटर्न के प्रेरक मामलों पर यहां चर्चा नहीं की गई है। हालाँकि, स्मृति को बचाना निश्चित रूप से प्राथमिक उद्देश्यों में से एक होगा।


# 3 के लिए धन्यवाद, मुझे नहीं पता :)
kaay

4

आपको दो समयावधि का समय निकालना चाहिए जो कि संकलन समय और रनटाइम समय हैं। उदाहरण के लिए:

//example 1 
"test" == "test" // --> true 
"test" == "te" + "st" // --> true

//example 2 
"test" == "!test".substring(1) // --> false
"test" == "!test".substring(1).intern() // --> true

एक हाथ में, उदाहरण 1 में, हम पाते हैं कि परिणाम सभी सही हैं, क्योंकि संकलन समय में, जेवीएम "परीक्षण" को शाब्दिक तार के पूल में डाल देगा, अगर जेवीएम "परीक्षण" मौजूद है, तो यह मौजूद एक का उपयोग करेगा, उदाहरण 1 में, "परीक्षण" तार सभी एक ही मेमोरी पते के लिए इंगित करते हैं, इसलिए उदाहरण 1 सच हो जाएगा। दूसरे हाथ में, उदाहरण 2 में, विकल्प की विधि () रनटाइम समय में निष्पादित होती है, "परीक्षण" == "परीक्षण!" .substring (1) के मामले में, पूल दो स्ट्रिंग ऑब्जेक्ट बनाएगा, " परीक्षण "और" परीक्षण ", इसलिए वे अलग-अलग संदर्भ वस्तुएं हैं, इसलिए यह मामला" परीक्षण = == "परीक्षण!" के मामले में गलत वापस आ जाएगा। substring (1) .intern (), इंटर्न की विधि। ) "" परीक्षण ""। substring (1) "को शाब्दिक तार के पूल में डाल देगा,"


3

http://en.wikipedia.org/wiki/String_interning

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


2

आंतरिक स्ट्रिंग्स डुप्लिकेट स्ट्रिंग्स से बचें। डुप्लिकेट स्ट्रिंग्स का पता लगाने और बदलने के लिए अधिक सीपीयू समय की कीमत पर इंटरस्टिंग रैम बचाता है। प्रत्येक स्ट्रिंग की केवल एक प्रति है जिसे नजरबंद कर दिया गया है, इससे कोई फर्क नहीं पड़ता कि कितने संदर्भ इंगित करते हैं। चूंकि स्ट्रिंग्स अपरिवर्तनीय हैं, अगर दो अलग-अलग विधियां संयोग से एक ही स्ट्रिंग का उपयोग करती हैं, तो वे एक ही स्ट्रिंग की एक प्रति साझा कर सकते हैं। डुप्लिकेट किए गए स्ट्रिंग्स को साझा करने की प्रक्रिया को इंटर्नशिप करने के लिए कहा जाता है। Sringing.tern.intern () आपको विहित मास्टर स्ट्रिंग का पता देता है। आप साधारण स्ट्रिंग्स के साथ इंटर्नड स्ट्रिंग्स की तुलना कर सकते हैं = (जो पॉइंटर्स की तुलना करता है) बराबरी के बजायजो एक-एक करके स्ट्रिंग के पात्रों की तुलना करता है। क्योंकि स्ट्रिंग्स अपरिवर्तनीय हैं, इसलिए आंतरिक प्रक्रिया अंतरिक्ष को बचाने के लिए स्वतंत्र है, उदाहरण के लिए, "पॉट" के लिए एक अलग स्ट्रिंग शाब्दिक नहीं बनाकर जब यह "हिप्पोपोटेमस" जैसे कुछ अन्य शाब्दिक के विकल्प के रूप में मौजूद है।

अधिक देखने के लिए http://mindprod.com/jgloss/interned.html


2
String s1 = "Anish";
        String s2 = "Anish";

        String s3 = new String("Anish");

        /*
         * When the intern method is invoked, if the pool already contains a
         * string equal to this String object as determined by the
         * method, then the string from the pool is
         * returned. Otherwise, this String object is added to the
         * pool and a reference to this String object is returned.
         */
        String s4 = new String("Anish").intern();
        if (s1 == s2) {
            System.out.println("s1 and s2 are same");
        }

        if (s1 == s3) {
            System.out.println("s1 and s3 are same");
        }

        if (s1 == s4) {
            System.out.println("s1 and s4 are same");
        }

आउटपुट

s1 and s2 are same
s1 and s4 are same

2
String p1 = "example";
String p2 = "example";
String p3 = "example".intern();
String p4 = p2.intern();
String p5 = new String(p3);
String p6 = new String("example");
String p7 = p6.intern();

if (p1 == p2)
    System.out.println("p1 and p2 are the same");
if (p1 == p3)
    System.out.println("p1 and p3 are the same");
if (p1 == p4)
    System.out.println("p1 and p4 are the same");
if (p1 == p5)
    System.out.println("p1 and p5 are the same");
if (p1 == p6)
    System.out.println("p1 and p6 are the same");
if (p1 == p6.intern())
    System.out.println("p1 and p6 are the same when intern is used");
if (p1 == p7)
    System.out.println("p1 and p7 are the same");

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

जब आप उपयोग करते हैं String s = new String(hi), जावा स्ट्रिंग का एक नया उदाहरण बनाता है, लेकिन जब आप उपयोग करते हैं String s = "hi", तो जावा यह जांचता है कि कोड में "हाय" शब्द का उदाहरण है या नहीं और यदि मौजूद है, तो यह केवल संदर्भ देता है।

चूंकि स्ट्रिंग्स की तुलना करना संदर्भ पर आधारित है, इसलिए intern()आपको एक संदर्भ बनाने में मदद करता है और आपको स्ट्रिंग्स की सामग्री की तुलना करने की अनुमति देता है।

जब आप intern()कोड का उपयोग करते हैं, तो यह उसी ऑब्जेक्ट का संदर्भ देते हुए स्ट्रिंग द्वारा उपयोग किए गए स्थान को साफ करता है और स्मृति में पहले से मौजूद उसी ऑब्जेक्ट के संदर्भ को वापस करता है।

लेकिन पी 5 के मामले में जब आप उपयोग कर रहे हैं:

String p5 = new String(p3);

केवल p3 की सामग्री की प्रतिलिपि बनाई गई है और p5 को नया बनाया गया है। इसलिए इसे नजरबंद नहीं किया गया है

तो उत्पादन होगा:

p1 and p2 are the same
p1 and p3 are the same
p1 and p4 are the same
p1 and p6 are the same when intern is used
p1 and p7 are the same

2
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s1 = "test";
    String s2 = new String("test");
    System.out.println(s1==s2);              //false
    System.out.println(s1==s2.intern());    //true --> because this time compiler is checking from string constant pool.
}

1

स्ट्रिंग इंटर्न () विधि का उपयोग स्ट्रिंग निरंतर पूल में ढेर स्ट्रिंग ऑब्जेक्ट की एक सटीक प्रतिलिपि बनाने के लिए किया जाता है। स्ट्रिंग स्थिर पूल में स्ट्रिंग ऑब्जेक्ट स्वचालित रूप से इंटर्न किए गए हैं लेकिन ढेर में स्ट्रिंग ऑब्जेक्ट नहीं हैं। इंटर्न बनाने का मुख्य उपयोग मेमोरी स्पेस को बचाने और स्ट्रिंग ऑब्जेक्ट्स की तेजी से तुलना करने के लिए है।

स्रोत: जावा में स्ट्रिंग इंटर्न क्या है?


1

जैसा कि आपने कहा, स्ट्रिंग intern()विधि पहले स्ट्रिंग पूल से मिल जाएगी, अगर यह मिल जाती है, तो यह उस वस्तु को वापस कर देगा जो उस ओर इंगित करता है, या पूल में एक नया स्ट्रिंग जोड़ देगा।

    String s1 = "Hello";
    String s2 = "Hello";
    String s3 = "Hello".intern();
    String s4 = new String("Hello");

    System.out.println(s1 == s2);//true
    System.out.println(s1 == s3);//true
    System.out.println(s1 == s4.intern());//true

s1और s2स्ट्रिंग पूल "हैलो" की ओर इशारा करते हैं, और का उपयोग कर दो वस्तुओं रहे हैं "Hello".intern()कि मिल जाएगा s1और s2। तो "s1 == s3"सही है, साथ ही साथ s3.intern()


यह वास्तव में बहुत नई जानकारी प्रदान नहीं करता है। पहले से ही एक अपवादित उत्तर है।
अलेक्जेंडर

0

हीप ऑब्जेक्ट संदर्भ का उपयोग करके यदि हम संबंधित स्ट्रिंग स्थिर पूल ऑब्जेक्ट संदर्भ प्राप्त करना चाहते हैं , तो हमें इंटर्न के लिए जाना चाहिए ()

String s1 = new String("Rakesh");
String s2 = s1.intern();
String s3 = "Rakesh";

System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true

सचित्र दृश्य यहां छवि विवरण दर्ज करें

चरण 1: डेटा के साथ ऑब्जेक्ट 'राकेश' ढेर और स्ट्रिंग निरंतर पूल में बनाया जाता है। इसके अलावा s1 हमेशा ऑब्जेक्ट को ढेर करने की ओर इशारा करता है।

चरण 2: हीप ऑब्जेक्ट रेफरेंस s1 का उपयोग करके, हम इसी स्ट्रिंग को निरंतर पूल ऑब्जेक्ट रेफरेंस s2 प्राप्त करने की कोशिश कर रहे हैं, इंटर्न का उपयोग करते हुए)

चरण 3: स्ट्रिंग निरंतर पूल में डेटा 'राकेश' के साथ जानबूझकर एक ऑब्जेक्ट बनाना, नाम s3 द्वारा संदर्भित

जैसा कि "==" ऑपरेटर संदर्भ तुलना के लिए था।

S1 == s2 के लिए गलत हो रहा है

S2 == s3 के लिए सही हो रहा है

उममीद है कि इससे मदद मिलेगी!!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.