jdk分析之String
public class StringDemo01 {
public static void main(String[] args) {
String s1 = new String("abc"); // a
String s2 = "abc"; // b
String s3 = new String("abc"); // c
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false
System.out.println(s1 == s1.intern()); //false
System.out.println(s2 == s2.intern()); //true
System.out.println(s1.intern() == s2.intern()); //true
String lo = "lo";
String hel = "hel";
System.out.println("hello" == "hel" + "lo"); // d //true
System.out.println("hello" == "hel" + lo); // e //false
System.out.println("hello" == hel + "lo"); // f //false
}
}
1、生成几个对象
问题:当执行完程序的第a、b、c行之后分别生成几个对象,分别是什么?原因?
1)执行完a后,生成2个对象:
首先先到String Pool中寻找是否有名称为"abc"的字符串,没有的话在String Pool中新生成一个"abc"对象1,而new String("abc")操作又会在Java内存的堆中生成一个"abc"String类对象2,
变量s1是一个引用,存放在栈中并指向堆中的"abc"String对象;
2) 执行完b后,生成0个对象:
String s2= "abc"; 此句程序在执行过程中也会先到String Pool中寻找名称为"abc"的字符串对象,因为在String s1 = new String("abc");时已经在String Pool中生成了"abc"对象,故执行完
这句之后同样存在于栈的s2对象指向String Pool中的"abc"String对象,即s2中存放"abc"String对象在String Pool中的地址;
3) 执行完c后,生成1个对象:
同样的道理,首先会到String Pool中查找是否有"abc"String对象,发现已经存在,然后又通过new的方式在中生成一个新的"abc"String对象,并将其地址赋给引用变量s3;
在此示例中三个引用变量s1、s2、s3分别指向三个不同的对象,存放着三个不同的内存地址,故三者当中任意者用"=="来比较都是false。
s1--------堆中的一个对象,此对象是String Pool中对象的一个拷贝;
s2--------String Pool常量池中的"abc"String对象;
s3--------堆中的一个对象,此对象也是String Pool中对象的一个拷贝;
==判断小结:
1)对于原生数据类型来说"=="比较的是数据的数值;
2)对于引用数据类型来说"=="比较的永远是对象的内存地址 。
2、intern
查看JDK文档可知如果有两个String类型s和t,当且仅当s.equals(t)时,s.intern()==t.intern(),即如果s和t的内容相等时s.intern()和t.intern()都是返回String Pool中同一个对象的引用,
既然是同一个对象的引用地址肯定一样。 分析s.intern()可知,首先到String Pool常量池中查找是否有"abc"字符串,如果有那么s.intern()的返回值就是常量池中"abc"的地址,如果没有,那么会先添加到string pool中去,然后将地址返回。
所以可以得到如下关系:s.intern()=s1.intern()=s2.intern()=s1
s1指向的是堆,而s1.intern()指向的是常量池中;
s2指向的是常量池,s2.intern()指向的也是常量池;
s1. intern()指向的是常量池,s2.intern()指向的也是常量池;
3、字符串拼接
对于第d行"+"两端是两个字面值即常量,故会拼接成一个"hello",然后在String Pool常量池中可以找到,不生成新的对象,等号两端的地址都是String Pool中" hello"的地址,所以相等,返回true。
对于第e,f行"+"两端其中一个是字面值即常量而另一个则是变量,无法进行拼接,故会在堆中生成一个"abc"的对象,堆中一个对象和String Pool常量池中一个对象当然是两个对象,地址值肯定不相
等,所以返回false。
常量池:JVM中一块独立的区域存放字符串常量和基本类型常量(public static final)
4、在Java中一个字符串能否表示一个汉字?
在Java中一个字符表示16位,相当于两个字节(1 byte = 8 bit),而一个汉字占用两个字节。
5、String s = "Hello"; s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有?
String对象的内容是不能改变的,最后虽然指向了helloworld,但是原始的String对象的内容还是hello并没有改变,只是现在不指向它罢了。
6、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?
创建了2个对象,一个在string pool中一个在堆中
7、String 和StringBuffer的区别
String是final类型,内容不可改变的,StringBuffer的内容是可以改变的;
String重写了equals和hashCode方法,而StringBuffer则没有。
8、StringBuffer和StringBuilder的区别
StringBuffer是线程安全的;
StringBuilder是非线程安全的性能高点,推荐使StringBuilder,JDK5以后出现。
9、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d"
一个。JVM在编译时会优化,相当于直接定义了一个”abcd”的字符串;
String s = "a"+"b"+"c";会生成几个对象?
只会生成一个对象,编译期就能确定存储到常量池中。
使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在堆中;
10、String练习
String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
String str5 = new String("ab"); System.out.println(str5.equals(str3)); //true
System.out.println(str5 == str3); //false
System.out.println(str5.intern() == str3); //true
System.out.println(str5.intern() == str4); //false String a = new String("ab");
String b = new String("ab");
String c = "ab";
String d = "a" + "b";
String e = "b";
String f = "a" + e; System.out.println(b.intern() == a); //false
System.out.println(b.intern() == c); //true
System.out.println(b.intern() == d); //true
System.out.println(b.intern() == f); //false
System.out.println(b.intern() == a.intern()); //true String a = "abc";
String b = "abc";
String c = "a" + "b" + "c";
String d = "a" + "bc";
String e = "ab" + "c"; System.out.println(a == b); //true
System.out.println(a == c); //true
System.out.println(a == d); //true
System.out.println(a == e); //true
System.out.println(c == d); //true
System.out.println(c == e); //true
jdk分析之String的更多相关文章
- java 源码分析1 -String
1. String的本质是一个 char数组,实现了CharSequence 接口, /** The value is used for character storage. */ private f ...
- JDK源码分析系列---String,StringBuilder,StringBuffer
JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...
- 【JDK源码分析】String的存储区与不可变性
// ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...
- 【JDK源码分析】String的存储区与不可变性(转)
// ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...
- 【JDK源码分析】String的存储区与不可变 专题
<Think in Java>中说:“关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系”. "=="判断的是两个对象的内存地址是否一样,适用于 ...
- 说说JDK中的String.valueOf()传null的诡异处理
都说JDK的实现诡异多,今儿也算是被我踩到一个坑了. 就来说说关于String.valueOf的这个坑. public class TestString { public static void ma ...
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- JDK分析工具&JVM垃圾回收(转)
转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...
- JAVA基础之——JDK分析io、nio
在哪儿:jdk\jre\lib\rt.jar package java.io; package java.nio; 1 分类 1.1 IO 持久化序列化对象并压缩步骤 new FileOutput ...
随机推荐
- windows下脚本配置IP地址
带着笔记本有时候在固定的地方工作,需要用到同一个的Ip地址.换个地方换个Ip,又要重新输一遍. 开始感觉这个过程很繁琐,因为是window工作环境,一开始想到了vbs脚本. 无意中发现了强大的nets ...
- HTML5 javascript修改canvas的大小
方法1: 设定固定的值,这种方式跟在html中设定canvas的值没有什么区别: window.onload = function(){ canvas.height = 100; canvas.wid ...
- 多线程编程之Linux环境下的多线程(三)
前面两篇文章都讲述了Linux环境下的多线程编程基础知识,也附带了典型实例.本文主要比较一下Linux环境与Windows环境下的多线程编程区别. 看待技术问题要瞄准其本质,不管是WIN32.Linu ...
- 在程序中使用gettid()的方法
gettid()这个函数不可以在程序中直接使用,它是linux本身的一个函数,直接使用会出现,尚未声明之类的错误. 我们可以自已定义实现方法,如下: #include <sys/syscall. ...
- 去掉IntelliJ IDEA的拼写检查
Settings→Editor→Inspections→Spelling 去掉Spelling下的Typo复选框即可 来自为知笔记(Wiz)
- C#将字符串转换为整型的三种方法的总结
在C#中,要将一个字符串或浮点数转换为整数,基本上有三种方法: (1)使用强制类型转换:(int)浮点数 (2)使用Convert.ToInt32(string) (3)使用int.Parse(str ...
- .NET简谈构件系统开发模式
转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...
- VB脚本调用exe应用程序并传递参数
VB脚本调用应用程序,并传递参数给exe应用程序: Private Sub CommandButton1_Click() Dim a a = Shell("D:\\ExperimentLin ...
- Java的最大优势还是跨平台么?
之前码农界有码农说Java的最大优势是跨平台,真的是这样么?其实当时网络没这么火爆的时候,确实是这样的,但现在这已然不是了. 跨平台还是Java的最大优势么? 有跨平台需求的仅仅是客户端应用,而不是服 ...
- vs2012出现无法启动iis express web 服务器的错误
一直用的好好的,今天调试时却总报上面的错误.“文件查看器”->"windows 日志"->"系统"里发现有几条“HttpEvent”错误, 具体信息 ...