Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added explanation of performance WRT interning strings.

...

Code Block
bgColor#FFcccc
public class ExampleComparison {
  public static void main(String[] args) {
    String str1 = new String("one");
    String str2 = new String("one");
    boolean result;
    // test belowfor null is redundant in this case, but required for full generality
    if (str1 == null) { 
      result = str2 == null;
    }
    else {
      result = str1 == str2;
    }
    System.out.println(result); // prints false
  }
}

...

Code Block
bgColor#ccccff
public class GoodComparison {
  public static void main(String[] args) {
    String str1 = new String("one");
    String str2 = new String("one");
    boolean result;

    // test for null is redundant in this case, but required for full generality
    if (str1 == null) {
      result = (str2 == null);
    } else {
      result = str1.equals(str2);
    }
    System.out.println(result); // prints true
  }
}

...

Code Block
bgColor#ccccff
public class GoodComparison {
  public static void main(String[] args) {
    String str1 = new String("one");
    String str2 = new String("one");
    boolean result;

    // test for null is redundant in this case, but required for full generality
    if (str1 != null) {
      str1 = str1.intern();
    }

    // test for null is redundant in this case, but required for full generality
    if (str2 != null) {
      str2 = str2.intern();
    }
    result = str1 == str2;

   System.out.println(result); // prints true
  }
}

Use this approach with care; performance and clarity could be better served by of String.intern() should be reserved for cases where tokenization of strings either yields an important performance enhancement or dramatically simplifies code. The performance and readability is often improved by the use of code that applies the Object.equals() approach and lacks any dependence on reference equality.

The performance issue arises because:

  • the cost of String.intern() grows as the number of intern strings grows. Performance should be no worse than n log n, but the JLS makes no guarantee.
  • strings that have been interned become immortal; they cannot be garbage collected. This can be problematic when large numbers of strings are interned.

Exceptions

EXP01-EX1: Use of reference equality in place of object equality is permitted only when the defining classes guarantee the existence of, at most, one object instance for each possible object value. This generally requires that instances of such classes are immutable. The use of static factory methods rather than public constructors facilitates instance control; this is a key enabling technique.

...