点击上方“好好学java”,选择“置顶公众号”

优秀学习资源、干货第一时间送达!

好好学java

java知识分享/学习资源免费分享

关注

精彩内容

你所需要的java全套视频教程

你所需要的java电子图书

你所需要的大数据视频教程

你所需要的java练习项目

String的深入解析

  • 首先String不属于8种基本数据类型,String是一个对象。
         因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

  • new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;

  • -

1String str=”kvill”;
2    String str=new String (“kvill”);

的区别:

  在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。
  常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量

例1:

1String s0=”kvill”;
2String s1=”kvill”;
3String s2=”kv” + “ill”;
4System.out.println( s0==s1 );
5System.out.println( s0==s2 );

结果为:
true
true

  首先,我们要知道Java会确保一个字符串常量只有一个拷贝。
  因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。
  所以我们得出s0==s1==s2;

  用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

例2:

1String s0=”kvill”;
2String s1=new String(”kvill”);
3String s2=”kv” + new String(“ill”);
4System.out.println( s0==s1 );
5System.out.println( s0==s2 );
6System.out.println( s1==s2 );

结果为:
false
false
false

例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。

String.intern():

  再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了

 1String s0= “kvill”; 2String s1=new String(”kvill”); 3String s2=new String(“kvill”); 4System.out.println( s0==s1 ); 5System.out.println( “**********” ); 6s1.intern(); 7s2=s2.intern(); //把常量池中“kvill”的引用赋给s2 8System.out.println( s0==s1); 9System.out.println( s0==s1.intern() );
10System.out.println( s0==s2 );

结果为:
false
** false //虽然执行了s1.intern(),但它的返回值没有赋给s1
true //说明s1.intern()返回的是常量池中”kvill”的引用
true

最后我再破除一个错误的理解:

  有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:

1String s1=new String("kvill");
2String s2=s1.intern();
3System.out.println( s1==s1.intern() );
4System.out.println( s1+" "+s2 );
5System.out.println( s2==s1.intern() );

结果:
false
kvill kvill
true

在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。
  s1==s1.intern()为false说明原来的“kvill”仍然存在
  s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。

参考资料
  • http://darrenyjy.github.io/2016/05/28/String%E6%B1%A0%E5%8C%96%E5%8F%8Aintern%E6%96%B9%E6%B3%95%E7%9A%84%E4%BD%9C%E7%94%A8/

  • http://www.debugease.com/j2se/428295.html

  • http://www.cnblogs.com/Qian123/p/5707154.html

附上热门QQ群,存放资源和历史资料,500容量(低门槛付费群),长按二维码入群


长按二维码关注

Java基础提升篇:理解String 及 String.intern() 在实际中的应用相关推荐

  1. 你所需要的java基础提升篇大总结

    java基础篇深入解析大总结 java基础(一) 深入解析基本类型 java基础(二) 自增自减与贪心规则 java基础(三) 加强型for循环与Iterator java基础(四) java运算顺序 ...

  2. Java基础提升篇:equals()与hashCode()方法详解

    概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() Object类是类继承 ...

  3. java基础提升篇:synchronized同步块和volatile同步变量

    初遇 Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低 ...

  4. Java基础提升篇:equals()方法和“==”运算符

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 你所需要的 ...

  5. java基础提升篇:深入分析Java的序列化与反序列化

    初遇 序列化是一种对象持久化的手段.普遍应用在网络传输.RMI等场景中.本文通过分析ArrayList的序列化来介绍Java序列化的相关内容.主要涉及到以下几个问题: 怎么实现Java的序列化 为什么 ...

  6. java基础提升篇:Java中Native关键字的作用

    初遇 初次遇见 native是在 java.lang.Object 源码中的一个hashCode方法: public native int hashCode(); 为什么有个native呢?这是我所要 ...

  7. 【通知】+ java基础提升篇:Java 序列化的高级认识

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 你所需要的 ...

  8. java基础提升篇:深入浅出Java多线程

    初遇 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特别的形式,但多线程 ...

  9. java基础提升篇:Java 序列化的高级认识

    如果你只知道实现 Serializable 接口的对象,可以序列化为本地文件.那你最好再阅读该篇文章,文章对序列化进行了更深一步的讨论,用实际的例子代码讲述了序列化的高级认识,包括父类序列化的问题.静 ...

最新文章

  1. oracle bulk collect
  2. antd Drawer 如何实现自动刷新
  3. Android Context 详解
  4. UVA11292杀怪
  5. 委托的Invoke 和 BeginInvoke 与Control的Invoke和BeginInvoke(转-因为写得很好)
  6. ESP8266编译环境 对于习惯Ubuntu默认桌面的用户非常好
  7. 企业使用云计算低效益怎么办?区块链或成良药
  8. 多吉搜索不能用了_「转载」一个纯粹的中文搜索引擎:「Doge Doge」多吉搜索
  9. 从校园情侣到教授夫妇,最好的科研爱情是一起进步
  10. 2.程序员的自我修养---编译和链接
  11. 计算机教室布线施工方案,最新计算机教室施工方案.docx
  12. 【Java 8 新特性】Java LocalDate 详解
  13. 一台 ZXHN F650(GPON ONU) 学习小记
  14. DoS攻击原理和防御方法
  15. 初三毕业班主任压力过大割喉自尽
  16. mbp适合程序员_听说这两款是最适合程序员编程的电脑
  17. 网站加入代码让网页以电脑端打开_发现一个超级好用的视频播放网站-酷播云...
  18. DBLP数据集XML使用python SAX解析 作者名字显示错误问题
  19. 主要讲解了构造器和伴生对象内容
  20. C语言使用CUDA中cufft函数做GPU加速FFT运算,与调用fftw函数的FFT做运算速度对比

热门文章

  1. stm32编译时报错 ..........ER_IROM1: File exists 的问题
  2. java ee domain作用_java EE应用概述
  3. C++ Primer 5th笔记(chap 19 特殊工具与技术)将成员函数用作可调用对象
  4. C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move
  5. MIMIC 以太坊医疗项目开发(1) Express Web Server介绍
  6. java筑基期(9)----ajaxjson(1)
  7. [密码学] RSA利用解密指数分解n
  8. buu Windows系统密码
  9. [core]-ARM Core的分类和总结
  10. win32线程学习总结(临界区,互斥体,事件,信号量)