字符串相等性仅通过引用检查

时间:2013-12-27 13:29:53

标签: java string

如我们所知,如果我们进行如下检查,则输出将为equal

String s1 = "stackoverflow";
String s2 = "stackoverflow";
if(s1==s2){
    System.out.println("equal");
}

所以我的问题是,如果我在我的应用程序中没有使用new运算符来创建String,并且所有字符串都是字面值,那么我是否可以仅使用上面给出的引用相等性?提前谢谢。

N.B:我正在写一个爬虫,所以我需要检查一下我是否已经访问了我目前持有的给定网址。我正在使用murmur hash,它为每个网址提供long但是有冲突,所以如果存在哈希冲突,我需要检查url字符串的内容。因此,对于性能,我只想比较两个字符串网址的引用相等性。我使用jsoup进行html解析。

3 个答案:

答案 0 :(得分:7)

  

如果我在我的应用程序中没有使用new运算符来创建String,并且所有字符串都是字面值,那么我是否可以仅使用上面给出的引用相等性?

如果您100%确定您正在处理的所有字符串都是纯字符串文字或编译时常量表达式,那么是。 <{3}}要求

  

String类型的编译时常量表达式总是“实例化”,以便使用String.intern方法共享唯一实例。

但是如果您从其他任何地方获取字符串(例如,从您的爬虫检索的网页中读取它们,或者使用非编译时常量的连接表达式构建它们),那么您必须使用.equals来比较它们按价值而非参考或明确.intern()

表达式是否是编译时常量并不总是很明显:

String s1 = "Stack";
String s2 = s1 + "Overflow"; // not a CTC

final String s1 = "Stack";
String s2 = s1 + "Overflow"; // _is_ a CTC, because s1 is a "constant variable"
                             // (final, with an initializer that is itself a CTC)

答案 1 :(得分:1)

不,你不能。 VM不保证所描述的行为,它是一种优化。要保证此行为,您需要调用String#intern()。

这只会保证参考平等。

但是进行性能测试,String#equals()可能更快:-)

答案 2 :(得分:1)

  

所以我的问题是,如果我在我的应用程序中没有使用new运算符来创建String,并且所有字符串都是字面值,那么我是否只能使用上面给出的引用相等?

是的,当然。由于它们在编译时得到解决,因此没有问题。

但请记住以下情况

       String s3= s2;
       String s4= s1+"";   //resolved at run time 
      System.out.println(s3==s4);  //false
      System.out.println(s3.equals(s4));//true

因此,除非您确定以后不会更改字符串,否则可以安全地使用==。