Когда «» == s ложно, но «» .equals (s) верно

EDIT Спасибо за быстрые ответы. Пожалуйста, посмотрите, каков реальный вопрос. Я сделал это смелым на этот раз.

Я понимаю разницу между == и .equals. Так что это не мой вопрос (на самом деле я добавил для этого некоторый контекст)

Я выполняю проверку ниже для пустых строк:

if( "" == value ) { 
    // is empty string 
} 

вpast при получении значений из базы данных или десериализации объектов из другого узла этот тестfailedпотому что два экземпляра строки действительно были разными ссылками на объекты, хотя они содержали одни и те же данные.

Таким образом, исправление для этих ситуаций было

if( "".equals( value ) ) {
   // which returns true for all the empty strings
}

Я в порядке с этим. Это ясно понято.

Сегодня это произошло еще раз, но меня это озадачило, потому что на этот раз приложение очень маленькоеstandalone application который не используетnetwork at allпоэтому новая строка не извлекается из базы данных и не десериализуется с другого узла.

Итак, вопрос:


Under which OTHER circumstances:
"" == value // yields false 

а также

"".equals( value ) // yields true

Для локального автономного приложения?

Я уверенnew String() не используется в коде.

И единственный способ, которым ссылка на строку может быть & quot; & quot; потому что ему назначается & quot; & quot; непосредственно в коде (или как я думал) как в:

String a = "";
String b = a;

assert "" == b ; // this is true 

Каким-то образом (после прочтения кода у меня есть подсказка) были созданы две разные ссылки на пустые строковые объекты, я хотел бы знатьhow

Больше в ответе jjnguys:

Байт!

EDIT: Conclusion

Я нашел причину.

После предложения jjnguy я смог взглянуть на код другими глазами.

Виновный метод: StringBuilder.toString ()

A new String object is allocated and initialized to contain the character sequence currently represented by this object.

Doh! ...

    StringBuilder b = new StringBuilder("h");
    b.deleteCharAt( 0 );
    System.out.println( "" == b.toString() ); // prints false

Тайна разгадана.

Код использует StringBuilder для работы с постоянно растущей строкой. Оказывается, в какой-то момент кто-то сделал:

 public void someAction( String string ) { 
      if( "" == string ) {
           return;
       }

       deleteBankAccount( string );
 }

и использовать

 someAction( myBuilder.toString() ); // bug introduced. 

постскриптум Я читал слишком много CodingHorror в последнее время? Или почему я чувствую необходимость добавить сюда несколько забавных картинок с животными?

Ответы на вопрос(10)

Ваш ответ на вопрос