String comparisons

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wmartin
    New Member
    • Jan 2008
    • 2

    String comparisons

    Now I'm new to Java, but I was under the impression that when using == to compare two Strings, java checked to see whether the objects where exactly the same rather than doing the character by character check that equals() performs.

    However, when I was just fiddling about, I wrote this:

    Code:
    public class Test
    {
       private String testString;
       private String compareString;
    
       public Test()
       {
           testString = "Hello World!";
           compareString = "Hello World!";
       }
       
       
       public void compareString()
       {   
           if(testString == compareString)
           {
               System.out.println("True");
           }
           else
           {
               System.out.println("False");
           }
       }
    }
    This however, prints the value True which surprised me as they are not the same String object as far as I'm concerned.

    I must be doing something very silly here, but I just can't understand what. Please advise a newbie :)
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Literal Strings are collected by the compiler and put in the String pool when the
    class is loaded. Strings such as "Hello World!" end up in that pool as one single
    String (i.e. they're a pointer to one single String object). That's why the ==
    operator returns true. Try to make one of those refefrences (pointers) as
    'new String("Hello World")' and see what happens then ...
    kind regards,

    Jos

    Comment

    • wmartin
      New Member
      • Jan 2008
      • 2

      #3
      Ah, perfect. Thank you for the explanation.

      Comment

      • Stubert
        New Member
        • Dec 2007
        • 20

        #4
        So let me get this right, when you delcare a single string "Hey there" it gets assigned to a location in memory, say Location 56 for example. Every new string that is declared which has the value "Hey there" just points to the memory location 56. Whereas if you create a new instance of the string it creates a new instance of it in memory too at location 57?

        Comment

        • BigDaddyLH
          Recognized Expert Top Contributor
          • Dec 2007
          • 1216

          #5
          Originally posted by Stubert
          So let me get this right, when you delcare a single string "Hey there" it gets assigned to a location in memory, say Location 56 for example. Every new string that is declared which has the value "Hey there" just points to the memory location 56. Whereas if you create a new instance of the string it creates a new instance of it in memory too at location 57?
          "Hey there" is a string literal. Yes, string literals are pooled.

          Comment

          • RedSon
            Recognized Expert Expert
            • Jan 2007
            • 4980

            #6
            Originally posted by BigDaddyLH
            "Hey there" is a string literal. Yes, string literals are pooled.
            What happens when you do
            [CODE=java]
            string hey = "hey there";
            string hay = "hey there";
            string heyHeyHey = hey + hay;

            hey += " you";
            [/CODE]
            If the JVM copies hey to another location in memory and appends you then that is a fairly expensive operation. Instead of just creating to memory blocks that both have "hey there" and appending "you" to the end of it, in the first place.

            Comment

            • BigDaddyLH
              Recognized Expert Top Contributor
              • Dec 2007
              • 1216

              #7
              I used javap to decompile that code:

              public static void main(java.lang. String[]);
              Code:
              0: ldc #2; //String hey there
              2: astore_1
              3: ldc #2; //String hey there
              5: astore_2
              6: new #3; //class java/lang/StringBuilder
              9: dup
              10: invokespecial #4; //Method java/lang/StringBuilder." <init>":()V
              13: aload_1
              14: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
              17: aload_2
              18: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
              21: invokevirtual #6; //Method java/lang/StringBuilder.t oString
              24: astore_3
              25: new #3; //class java/lang/StringBuilder
              28: dup
              29: invokespecial #4; //Method java/lang/StringBuilder." <init>":()V
              32: aload_1
              33: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
              36: ldc #7; //String you
              38: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
              41: invokevirtual #6; //Method java/lang/StringBuilder.t oString
              44: astore_1
              45: return
              }

              Comment

              • RedSon
                Recognized Expert Expert
                • Jan 2007
                • 4980

                #8
                Originally posted by BigDaddyLH
                I used javap to decompile that code:

                public static void main(java.lang. String[]);
                Code:
                0: ldc #2; //String hey there
                2: astore_1
                3: ldc #2; //String hey there
                5: astore_2
                6: new #3; //class java/lang/StringBuilder
                9: dup
                10: invokespecial #4; //Method java/lang/StringBuilder." <init>":()V
                13: aload_1
                14: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
                17: aload_2
                18: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
                21: invokevirtual #6; //Method java/lang/StringBuilder.t oString
                24: astore_3
                25: new #3; //class java/lang/StringBuilder
                28: dup
                29: invokespecial #4; //Method java/lang/StringBuilder." <init>":()V
                32: aload_1
                33: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
                36: ldc #7; //String you
                38: invokevirtual #5; //Method java/lang/StringBuilder.a ppend
                41: invokevirtual #6; //Method java/lang/StringBuilder.t oString
                44: astore_1
                45: return
                }
                Sorry BD, I don't speak bytecode. :(

                Comment

                • BigDaddyLH
                  Recognized Expert Top Contributor
                  • Dec 2007
                  • 1216

                  #9
                  Originally posted by RedSon
                  Sorry BD, I don't speak bytecode. :(
                  I can only order a beer in it, myself, but the way it sounds to me is that this code:
                  [CODE=Java]String x = "hey there";
                  String y = "hey there";
                  String z = x + y;
                  x += " you";[/CODE]
                  is executed like this (pseudo-codish)
                  [CODE=Java]STRINGPOOL NUM2 "hey there"
                  STRINGPOOL NUM7 "you"

                  String x = NUM2;
                  String y = NUM2;
                  String z = new StringBuilder() .append(x).appe nd(y).toString( );
                  x = new StringBuilder() .append(x).appe nd(NUM7).toStri ng();[/CODE]
                  In reply #6, you mentioned appending to a memory block as what "+=" could do, but I don't think Strings in Java would ever be implemented that way.

                  One may have hoped for more optimization -- why use StringBullder to concatenate strings whose value is fixed? Well, final can come to the rescue. Consider this little program:

                  [CODE=Java]public class H {
                  public static void main(String[] args) {
                  final String x = "hey there";
                  final String y = "hey there";
                  final String z = x + y;
                  f(z);
                  }

                  static void f(String s){}
                  }[/CODE]
                  Running the disassembler on this code shows that final helps. Here is the code for main:

                  public static void main(java.lang. String[]);
                  Code:
                  0: ldc #2; //String hey therehey there
                  2: invokestatic #3; //Method f:(Ljava/lang/String;)V
                  5: return

                  Comment

                  Working...