2

I was reading about String in java and was trying to understand it.

At first, it was easy how String s1="11" and String s2=new String ("11") works(created) and I understood intern method also.
But I came across this example (Given by a friend) and made me confused about everything.

I need help to understand this.

String s1 = new String(new String("2")+new String("2"));
s1.intern();
String s2="22";
System.out.print(s1==s2);  //=>true as output.
String s3 =new String (new String("2")+new String("2"));
s3.intern();
String s4="22";
System.out.print(s3==s4);  //=>false as output.

Answer of this code is true and false.

Part for S1 and s2 was good and was true according to my understanding but the second part I didn't understand.

Hope someone can break the code line by line and help me understand.

user207421
  • 305,947
  • 44
  • 307
  • 483
aatif
  • 147
  • 1
  • 1
  • 8
  • `String` references are immutable. `s3 = s3.intern();` And you'll get `true`. As for the first example, look at the order of execution - put `String s2 = "22";` **before** `String s1 = //...` for `false`. – Elliott Frisch Mar 19 '17 at 06:28
  • @ElliottFrisch could you elaborate more on the first case. I find both the cases same, except we have different variables. How come on the first case we get `true`, while the second one gives `false`, even though the order of execution is same for both the cases – dumbPotato21 Mar 19 '17 at 06:33
  • Move the declaration of `s2` to before `s1` for a *surprise*. And then move it to **before** the `s1.intern();` for the ***same** surprise*. Finally, `s2` is the same reference as `s4` (`s2 == s4` is `true`). – Elliott Frisch Mar 19 '17 at 06:36
  • Thanks @EJP for edit – aatif Mar 19 '17 at 07:05
  • @ElliottFrisch LOL i am all suprised and shocked But there must be answer for this . Both situation are same declaration and assignment on both cases are exact replica. But the question remains why true for one and false for other – aatif Mar 19 '17 at 07:08
  • Because `String s2="22";` searches the intern pool for `"22"` (to dis-spell the mystery, and to clear your confusion, read the [`String.intern()`](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--) javadoc). – Elliott Frisch Mar 19 '17 at 07:13
  • @ElliottFrisch I read it Sir and everything I read making me more confused. can you please break the line by line and help me and many people here understand what is happening with it? It will be helpful – aatif Mar 19 '17 at 07:15
  • The two most relevant lines from the link are *A pool of strings, initially empty, is maintained privately by the class `String`.* **and** *All literal strings and string-valued constant expressions are interned.*; think about the order in which the literal strings are intern()'d. And note that to `intern()` `s1` you would write `s1 = s1.intern();` (like I already commented about `s3`). Finally, note that `new String` is **not** a literal string ***or*** a string-valued constant expression; so if you say `new String` it is not `intern`(d). – Elliott Frisch Mar 19 '17 at 07:24

5 Answers5

2

s1.intern(); adds s1 to the pool of strings, therefore the string "22" is now in the pool of strings. Therefore when you write s2 = "22" that's the same "22" as s1 and thus s1 == s2.

s3.intern() does NOT add s3 to the pool of strings because the string "22" is already there.

s3.intern() does return that same "22" which is s1 BUT IT IS NOT USED. Therefore s3 is not equal s4.

Alexander Kulyakhtin
  • 47,782
  • 38
  • 107
  • 158
0

Notice that the type String is capitalized and is not one of Java's 8 primitive types (int, boolean, double, char, etc.). This indicates that any instance of a String is an object that was built using the 'blueprint' of the class String. Because variables in Java that refer to objects only store the memory address where the actual object is stored, when you compare Strings with == it compares memory location.

String str1 = new String("hello");
String str2 = str1; //sets str1 and str2 pointing to same memory loc
if (str1 == str2){
    //do stuff; the code will enter this if-statement in this case
}

The way to compare the values within objects in Java is with equals(), such as:

String str1 = new String("hello");
String str2 = new String("hello"); //str2 not same memory loc as str1
if (str1.equals(str2)){
    //do stuff; the code will enter this if-statement in this case
}

This is a common error for beginners, since the primitive types are not objects and you CAN compare two ints for equality like:

int one = 1; //primitive types are NOT objects
int two = 2; //notice when I make an int, I don't have to say "new"
             //which means a new **object**
if (int1 == int2) {
    //do stuff; in this case the program will not enter this if-statement
}

It seems that you understand everything but the meaning of the very last line. See my comment on the last line.

String s1 = new String(new String("2")+new String("2")); //declare AND initialize s1 as a new String object
s1.intern();
String s2="22"; //declare a new variable s2 and point it to the same object that s1 is pointing to
System.out.print(s1==s2);
String s3 =new String (new String("2")+new String("2"));
s3.intern();
String s4="22";
System.out.print(s3==s4); //check if s3 and s4 are stored in the same memory location = FALSE
ashtree
  • 51
  • 5
  • this answer no where related to the question. The question isn't about the difference between `==` and `equals`, if it was it would have been marked as a duplicate. – dumbPotato21 Mar 19 '17 at 06:58
  • You're right. I was just trying to supplement the other answer. But I edited my answer to fit the question better. – ashtree Mar 19 '17 at 07:04
  • @ashtree But what about s1==s2 ? Why it returns true. Both scenario are exact same . – aatif Mar 19 '17 at 07:11
  • Look at the statement when `String s2` is declared but, importantly, NOT initialized with `new` and an object. You're NOT saying something like `String s2 = new String("hello");` ... you're saying, I declare `String s2`, and it is a variable that is now set to an already existing object `s1` ( once again, because we're not creating a new one with the `new` keyword). The variable `s1` is a reference to a location in memory because it is associated with an object. `s1` was created with `new` and `String("dog");` but `s2` was NOT. – ashtree Mar 19 '17 at 07:19
  • @aatif I added a couple more comments in my answer describing your code line by line. Let me know if there are any more lines that need clarifying. – ashtree Mar 19 '17 at 07:25
0

In java exist the heap and the stack, Heap is where all Objects are saved stack is where vars are saved Now also exist another kind of list for Strings and Integers (numbers)

As you know a String can be created in some ways like

like new String("word") or just = "word" when you use the first way you create a new object (heap) when you use the other you save the word in a stack of words (Java engenniers thought it would be good if you don't create manny objects or words are repeated so they created an special stack for words, same for Integers from 0 to 127) So as I said You have to know that there is an stack and a Heap look at this example

String wordOne ="hola";
        String wordTwo = "hola";
        String wordTres = "hola";
        System.out.println(wordOne == wordTwo);
        System.out.println(wordTres == wordTwo);
        System.out.println(wordOne == wordTres);

        String wordFour = new String("hola");
        System.out.println(wordOne == wordFour);

        Integer uno = 127;
        Integer dos = 127;
        System.out.println(uno == uno);
        Integer tres = 128;
        Integer cuatro = 128;
        System.out.println(tres == cuatro);

String x = "word"; is saved in an special Stack String y = new String("it is not");

But tbh I don't remeber so well the rules for tha stack, but in any case i recomend you to compare all words using wordX.equals(wordY)

An also numbers in objects could be compared using == from 0 to 127 but the same if you use objects use equals, although using numbers there is a better do to do it in spite of use equals, convert one number to a primitive value (the memory will be better)

enter image description here

Yussef
  • 610
  • 6
  • 11
0

When you are making string with new keyword,JVM will create a new string object in normal(non pool) heap memory and the literal will be placed in the string constant pool. In your case, The variable s1 will refer to the object in heap(non pool).

String s1 = new String(new String("2")+new String("2"));

But in the next line your are calling intern() method.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) 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.

Check Javadocs. As "22" is not in string pool, a new string literal "22" will be created and a reference of it will be returned. When you are writing:

String s2="22";

it simply refers "22" in string pool. But calling s3.intern() will not create a new string literal as "22" exists in the pool. Check the Javadocs for intern() again. It says if exists in pool, then string from the pool is returned not reference. So, this time s3 references to a different object. But s4 is referred to same object as s1,s2. You can print the objects hashcode for checking if the are same or not. Like:

System.out.println(System.identityHashCode(s1));
Pial Kanti
  • 1,550
  • 2
  • 13
  • 26
-2

In java object1 == object2 means

that do object1 and object2 have the same address in memory?

object1.equals(object2)

means are they equal, for example do they have the same values of all fields?

So, For two Strings S1 and S2, string1.equals(S2) means, do they have the same characters in the same sequence?
S1 == S1 means are string1 and string2 stored at the same address in memory?

Hamza Anis
  • 2,475
  • 1
  • 26
  • 36