为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候应该在字符串文本上使用字符串的Intern方法?

什么时候应该在字符串文本上使用字符串的Intern方法?

长风秋雁 2019-06-28 16:43:08
什么时候应该在字符串文本上使用字符串的Intern方法?根据字符串#intern(), intern方法如果在字符串池中找到字符串,则应从字符串池返回字符串,否则将在String池中添加一个新的String对象,并返回该字符串的引用。所以我试了一下String s1 = "Rakesh";String s2 = "Rakesh";String s3 = "Rakesh".intern();if ( s1 == s2 ){     System.out.println("s1 and s2 are same");  // 1.}if ( s1 == s3 ){     System.out.println("s1 and s3 are same" );  // 2.}我还以为s1 and s3 are same将在S3被拘留时打印,以及s1 and s2 are same不会印刷。但结果是:这两条线都是打印出来的。这意味着,默认情况下,字符串常量是内嵌的。但如果是这样,那我们为什么需要intern方法?换句话说,我们什么时候应该使用这种方法?
查看完整描述

3 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

在最近的一个项目中,用从数据库读取的数据(因此不是字符串常量/文字)建立了一些巨大的数据结构,但是有大量的重复。这是一种银行应用程序,像一家规模不大的公司(可能是100家或200家)的名字,到处都是。数据结构已经很大了,如果所有这些公司名称都是唯一的对象,它们就会溢出内存。相反,所有数据结构都引用相同的100或200个字符串对象,从而节省了大量空间。

内嵌字符串的另一个小优点是==可以使用(成功!)要比较字符串,如果所有涉及的字符串都保证是内部的。除了更简洁的语法之外,这也是一种性能增强。正如其他人所指出的那样,这样做有引入编程错误的巨大风险,因此,这只能作为最后的手段。

缺点是,执行字符串需要花费更多的时间,而不是简单地将其抛到堆上,并且根据Java实现的不同,内部字符串的空间可能是有限的。这是最好的做法,当你处理一个已知的合理数量的字符串与许多重复。


查看完整回答
反对 回复 2019-06-28
?
慕仙森

TA贡献1827条经验 获得超8个赞

我想在使用时加上我的2分钱==带着实习的绳子。

第一件事String.equals是吗?this==object.

因此,尽管有一些微乎其微的性能增益(您不是在调用一个方法),但从维护人员的角度来看,使用==是一场噩梦,因为有些被拘留的字符串有成为非实习生的倾向。

所以我建议不要依赖特例==用于内部字符串,但始终使用equals就像高斯林想要的那样。

编辑:实习生变成非实习生:

V1.0public class MyClass{
  private String reference_val;

  ...

  private boolean hasReferenceVal ( final String[] strings )
  {
    for ( String s : strings )
    {
      if ( s == reference_val )
      {
        return true;
      }
    }

    return false;
  }

  private void makeCall ( )
  {
     final String[] interned_strings =  { ... init with interned values ... };

     if ( hasReference( interned_strings ) )
     {
        ...
     }
  }}

在2.0版本中,维护人员决定hasReferenceVal公开,但没有详细说明它需要一组内部字符串。

V2.0public class MyClass{
  private String reference_val;

  ...

  public boolean hasReferenceVal ( final String[] strings )
  {
    for ( String s : strings )
    {
      if ( s == reference_val )
      {
        return true;
      }
    }

    return false;
  }

  private void makeCall ( )
  {
     final String[] interned_strings =  { ... init with interned values ... };

     if ( hasReference( interned_strings ) )
     {
        ...
     }
  }}

现在您有了一个bug,这可能很难找到,因为在大多数情况下,数组包含文字值,有时使用非文字字符串。如果equals用而不是==然后hasReferenceVal还能继续工作。再一次,性能增益微乎其微,但维护成本很高。


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 537 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号