title: When "" == s is false but "".equals( s ) is true
body: <p><strong>EDIT</strong>
  Thanks for the prompt responses. Please see what the real question is. I have made it bold this time.</p>
  
  <p>I do understand the difference between == and .equals. So, that's not my question (I actually added some context for that)</p>
  
  <hr />
  
  <p>I'm performing the validation below for empty strings:</p>
  
  <pre><code>if( "" == value ) { 
      // is empty string 
  } 
  </code></pre>
  
  <p>In the <strong>past</strong> when fetching values from the db or deserializing objects from another node, this test <strong>failed</strong>, because the two string instances were indeed different object references, albeit they contained the same data.</p>
  
  <p>So the fix for those situations was</p>
  
  <pre><code>if( "".equals( value ) ) {
     // which returns true for all the empty strings
  }
  </code></pre>
  
  <p>I'm fine with that. That's clearly understood. </p>
  
  <p>Today this happened once again, but it puzzled me because this time the application is a very small <strong>standalone application</strong> that doesn't use <strong>network at all</strong>, so no new string is fetched from the database nor deserizalized from another node.</p>
  
  <p>So the question is:</p>
  
  <p><br></p>
  
  <h1>Under which <strong>OTHER</strong> circumstances:</h1>
  
  <pre><code>"" == value // yields false 
  </code></pre>
  
  <p>and </p>
  
  <pre><code>"".equals( value ) // yields true
  </code></pre>
  
  <p>For a local standalone application? </p>
  
  <p>I'm pretty sure <strong>new String()</strong> is not being used in the code.</p>
  
  <p>And the only way a string reference could be "" is because it is being assigned "" directly in the code (or that's what I thought) like in:</p>
  
  <pre><code>String a = "";
  String b = a;
  
  assert "" == b ; // this is true 
  </code></pre>
  
  <p>Somehow (after reading the code more I have a clue) two different empty string object references were created, I would like to know <strong>how</strong></p>
  
  <p>More in the line of jjnguys answer:</p>
  
  <p>Byte!</p>
  
  <p><strong>EDIT: Conclusion</strong></p>
  
  <p>I've found the reason. </p>
  
  <p>After jjnguy suggestion I was able to look with different eyes to the code.</p>
  
  <p>The guilty method: StringBuilder.toString()</p>
  
  <blockquote>
    <p><em>A new String object is allocated and initialized to contain the character sequence currently represented by this object.</em></p>
  </blockquote>
  
  <p>Doh!... </p>
  
  <pre><code>    StringBuilder b = new StringBuilder("h");
      b.deleteCharAt( 0 );
      System.out.println( "" == b.toString() ); // prints false
  </code></pre>
  
  <p>Mystery solved. </p>
  
  <p>The code uses StringBuilder to deal with an ever growing string. It turns out that at some point somebody did:</p>
  
  <pre><code> public void someAction( String string ) { 
        if( "" == string ) {
             return;
         }
  
         deleteBankAccount( string );
   }
  </code></pre>
  
  <p>and use </p>
  
  <pre><code> someAction( myBuilder.toString() ); // bug introduced. 
  </code></pre>
  
  <p>p.s. Have I read too much CodingHorror lately? Or why do I feel the need to add some funny animal pictures here?</p>