使用和不使用new运算符创建java字符串之间的区别

时间:2014-12-17 06:36:39

标签: java

使用new运算符String在堆中创建字符串并在字符串const池中放置一个副本,因此hashcode的结果在下面的情况下是相同的;

  String s1 = new String("Test");
   String s2 = new String("Test");
   System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));

但是,如果不使用new运算符,它仍会提供相同的哈希码

String s1 = new String("Test");
    String s2 = "Test";
    System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));

那么上面两个字符串创建符号之间的区别是什么,尽管它们在字符串const中引用相同的字符串。池

4 个答案:

答案 0 :(得分:0)

来自文档和Java.lang.String课程,hashCode()的内部实施

  

/ **        *返回此字符串的哈希码。一个哈希码        * String对象计算为        *

     * s[0]*31^(n-1) + s1*31^(n-2) + ... + s[n-1]
     * 
       *使用int算术,其中s[i]为。{1}}        * 字符串的字符,n是字符串的长度        *字符串,^表示取幂。        *(空字符串的哈希值为零。)        *        * @return此对象的哈希码值。        * /

public int hashCode() {
int h = hash;
    int len = count;
if (h == 0 && len > 0) {
    int off = offset;
    char val[] = value;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

有关String hashcode here

的更多信息

答案 1 :(得分:0)

 String str = new String("String");

总是在堆上创建一个新对象。

这里创建一个新的String,其值为常量的值&#34; String&#34;并指定其对变量str。

的引用
String str = "String";

使用String pool

这里指定与常量&#34; String&#34;相关联的引用。到变量str

答案 2 :(得分:0)

两个表达式都为您提供了String对象,但它们之间存在差异。使用new()运算符创建String对象时,它始终创建a new object in heap memory。另一方面,如果使用String文字语法创建对象,例如String s2 = "Test"; it may return an existing object from String pool(Perm gen空间中的String对象的缓存,现在已移至最近Java版本中的堆空间),如果它已经存在的话。否则,它将创建一个新的字符串对象并放入字符串池中以供将来重用。

进一步阅读请参阅:here

答案 3 :(得分:0)

基于Effective java

  

通常适合重用单个对象而不是创建   每次需要时,新的功能相当的对象。重用可以   更快更时尚。如果对象总是可以重用   是不可改变的。作为不做的极端例子,   考虑这个陈述:

     

String s = new String(&#34; stringette&#34;); // DON&#39; T.   做这个!

     

该语句每次都会创建一个新的String实例   已执行,并且这些对象创建都不是必需的。该   String构造函数的参数(&#34; stringette&#34;)本身就是一个   字符串实例,在功能上与创建的所有对象完全相同   由构造函数。如果此用法发生在循环中或频繁发生   调用方法,可以创建数百万个String实例   不必要。

     

改进版只是以下内容:

     

字符串s =&#34; stringette&#34 ;;

     

此版本使用单个String实例,而不是创建新实例   每次执行一次。此外,它保证了   对象将由在同一虚拟中运行的任何其他代码重用   碰巧包含相同字符串文字的机器

因此,创建不必要的新String或任何其他对象是很昂贵的。