String intern()方法详解

执行以下代码

  String a1=new String("abc");
       String a2=new String("abc");
       System.out.println(a1==a2);
       System.out.println(a1==a2.intern());
       System.out.println("abc"==a2.intern());
       System.out.println(a1.intern()==a2.intern());

返回

  false
  false
  true
  true

new String("abc") 方法是创建一个String对象, 同时引用常量池里的"abc", a1,a2分别是两块内存空间,a1!=a2; 而常量"abc"的引用是和a1,a2都不一样的, a1!=a2.intern(); "abc"是常量池的引用,和a2.intern()是指向同一个常量,所以"abc"==a2.intern()

JDK源码里有这么段说明

/**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class {@code String}.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {@code s} and {@code t},
     * {@code s.intern() == t.intern()} is {@code true}
     * if and only if {@code s.equals(t)} is {@code true}.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();

再来看看下面这段代码

        String a1="abc";
        String a2="abc";
        System.out.println(a1==a2);
        System.out.println(a1==a2.intern());
        System.out.println("abc"==a2.intern());
        System.out.println(a1.intern()==a2.intern());

全部返回true, a1,a2都是指向"abc"常量池

再来看看下面这段

  String a1="abc";
        String a2=new String("abc");
        System.out.println(a1==a2);
        System.out.println(a1==a2.intern());
        System.out.println("abc"==a2.intern());
        System.out.println(a1.intern()==a2.intern());

返回

  false
  true
  true
  true

PS: 相同字符串的intern()返回大部分情况是一样的, 因为存在调用了intern()方法后,该字符串被回收了,那么再次调用intern()会把相同的字符串加入到常量池里,但引用位置已经改变

原文地址:https://www.cnblogs.com/devilwind/p/7397158.html