2014-01-02 3 views
1

Я только начал изучать Java и наткнулся на это:Строковые литералы в Java

String s = "Hello"; 
String s1 = "Hello"; 
if(s.equals("Hello") && s.equals(s1)) 
{ 
    System.out.println("Equal"); 
} 

Первое условие в if заявлении сравнивает строку буквального s против последовательности символов, где в качестве второго заявление сравнивающих s против другой строковый литерал s1. Оба сравнения оказываются истинными.

Я понимаю, что s будет ссылаться на "Hello" и s1. Поскольку оба номера s и s1 содержат ссылки на "Hello", их можно сравнить и всегда равны (из-за «общего пула строк»).

Вопрос: Как может s, который содержит ссылку, сравниваться с фактической строкой "Hello", которая является символьной последовательностью? Есть ли какая-либо логика или это просто реализация, которая заботится о ссылках на память, а затем сравнивает эти два?

Пожалуйста, поправьте меня, если я понимаю неправильно ...

+1

s == «Привет» не совпадает с s.equals («Hello»). равно проверяет, равны ли строки и не совпадают ли ссылки. – schlingel

+0

помните, что '' '' '' '' '' '' '' не больше, чем угодно. Пул пула не является гарантией! – ljgw

+0

@ljgw - что вы имеете в виду под «как правило, равным. Пул строк не является гарантией!». – TheLostMind

ответ

6

Мой вопрос: Как можно «s», который содержит ссылку, можно сравнить с фактической строки «Hello», которая представляет собой последовательность символов?

"Hello" является не последовательность символов. Это String. (String действительно реализует CharSequence interface, но это не то же самое.) Итак, к тому времени, когда вы используете equals или ==, вы сравниваете экземпляры String, а не какую-то особую вещь. A String буква - a String (в комплекте с ссылкой на него, где буквально была написана в источнике).

Сначала казалось, что вы были смущены о equals и ==. Повторное чтение, я не уверен, что вы есть, но на всякий случай: equals сравнивает два объекта для эквивалентности; если два объекта: String s, он возвращает true, если они имеют одинаковую последовательность символов. == сравнивает две ссылки на объекты и оценивает true, если они указывают на тот же объект.== - это иногда true для того, что кажется другим String объектов, потому что String литералы неявно intern'd (помещены в общий пул и используются повторно), чтобы сохранить память, и поэтому два отдельных, но эквивалентных литерала на самом деле ссылаются на один и тот же объект. Никогда полагаться на это. Использование == для сравнения String s - это почти всегда ошибка (случаи, когда это не очень много краев). Используйте equals.

+0

Теперь я понимаю, почему я получил вниз. Я неправильно понял его вопрос (хотя у меня уже был мой кофе). – Maroun

+0

@MarounMaroun: Что вам нужно спать. :-) С Новым Годом! –

+0

Спасибо! С новым годом! Всего наилучшего :) – Maroun

0

Когда метод equals называется, то, что идет в стек является ссылка на то, что прошло. Поэтому, когда вы пишете s.equals("Hello"), одна из вещей в стеке - это ссылка на "Hello".

3

Вы вызываете метод equals, который сравнивает два объекта для эквивалентности - он не проверяет, что две ссылки относятся к одному экземпляру объекта. Чтобы проверить наличие двух ссылок на тот же объект, который вы будете использовать s == s1

2

если вы видите исходный код equals вы можете понять, что метод равно сравнивает значение строк каждого
характера. Если вы использовали ==, который будет сравнивать рефери.

public boolean equals(Object anObject) { 
     if (this == anObject) { 
      return true; 
     } 
     if (anObject instanceof String) { 
      String anotherString = (String)anObject; 
      int n = count; 
      if (n == anotherString.count) { 
       char v1[] = value; 
       char v2[] = anotherString.value; 
       int i = offset; 
       int j = anotherString.offset; 
       while (n-- != 0) { 
        if (v1[i++] != v2[j++]) 
         return false; 
       } 
       return true; 
      } 
     } 
     return false; 
    } 
0

Вопрос: Как s, который содержит ссылку, сравнивается с фактической строкой «Hello», которая является символьной последовательностью? Есть ли какая-либо логика или это просто реализация, которая заботится о памяти , а затем сравнивает два?

алгоритм для проверки строк равенства включает:

  1. Если объекты строк равны как на оператор ==, верно возвращается.
  2. Если значение == возвращает значение false, то каждый символ обеих строк сравнивается, и если обнаружено различие, то возвращается немедленное значение false.
  3. Если после сравнения всех символов обеих строк различия не найдены в символах и длине строк, возвращается значение true.

Ниже реализация defaullt из .equals() метода в классе Струнный:

public boolean equals(Object anObject) { 
     if (this == anObject) { 
     return true; 
     } 
     if (anObject instanceof String) { 
     String anotherString = (String)anObject; 
     int n = count; 
     if (n == anotherString.count) { 
      char v1[] = value; 
      char v2[] = anotherString.value; 
      int i = offset; 
      int j = anotherString.offset; 
      while (n-- != 0) { 
       if (v1[i++] != v2[j++]) 
       return false; 
       } 
      return true; 
      } 
     } 
     return false; 
    } 

Чтобы проверить две ссылки на тот же объект, который вы будете использовать s == s1.

Для сравнения двух значений используйте метод .equals().

Смежные вопросы