Search on the blog




package testPackage;

class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.println(hello == "Hello");
        System.out.println(Other.hello == hello);
        System.out.println(other.Other.hello == hello);
        System.out.println(hello == ("Hel" + "lo"));
        System.out.println(hello == ("Hel" + lo));
        System.out.println(hello == ("Hel" + lo).intern());

class Other {
    static String hello = "Hello";

package other;

public class Other {
    public static String hello = "Hello";
$ true
$ true
$ true
$ true
$ false
$ true

JLS 3.10.5には以下のように書いている。

Literal strings within the same class in the same package represent references to the same String object.
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct. 

  • 文字列の内容が同じリテラルはクラス/パッケージが違っても同じインスタンスを指す。 
  • コンパイル時に計算される文字列はリテラルと同様に扱われる。
  •  実行時に結合によって生成される文字列は新しいインスタンス化されるため、別インスタンスとなる。

String literals-or, more generally, strings that are the values of constant expressions -are "interned" so as to share unique instances, using the method String.intern.

internすることでリテラルは同じインスタンスが共有されるらしい。上のサンプルプログラムでもconcatenateした文字列を明示的にinternすることでインスタンスが共有されている。このinternとは何ぞや? Javadocを見てみる。

Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() ==t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java Language Specification.

0 件のコメント: