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的更多相关文章

  1. java 源码分析1 -String

    1. String的本质是一个 char数组,实现了CharSequence 接口, /** The value is used for character storage. */ private f ...

  2. JDK源码分析系列---String,StringBuilder,StringBuffer

    JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...

  3. 【JDK源码分析】String的存储区与不可变性

    // ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...

  4. 【JDK源码分析】String的存储区与不可变性(转)

    // ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...

  5. 【JDK源码分析】String的存储区与不可变 专题

    <Think in Java>中说:“关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系”. "=="判断的是两个对象的内存地址是否一样,适用于 ...

  6. 说说JDK中的String.valueOf()传null的诡异处理

    都说JDK的实现诡异多,今儿也算是被我踩到一个坑了. 就来说说关于String.valueOf的这个坑. public class TestString { public static void ma ...

  7. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  8. JDK分析工具&JVM垃圾回收(转)

    转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...

  9. JAVA基础之——JDK分析io、nio

    在哪儿:jdk\jre\lib\rt.jar package java.io;   package java.nio; 1 分类 1.1 IO 持久化序列化对象并压缩步骤 new FileOutput ...

随机推荐

  1. 【mybaits】Mybatis中模糊查询的各种写法

    工作中用到,写三种用法吧,第四种为大小写匹配查询 1. sql中字符串拼接 SELECT * FROM tableName WHERE name LIKE CONCAT(CONCAT('%', #{t ...

  2. .NET和java的RSA互通,仅此而已

    .NET和java的RSA互通,仅此而已 在开始这篇文章之前,先请读者朋友阅读老唐的这两篇文章: 1.Java与.Net环境下RSA加密解密交互不成功的问题解决 2.Java与.Net环境下RSA加密 ...

  3. objective-c 随便记记

    1.tableview滚动到某一位置 [tableViewShow setContentOffset:CGPointMake(0, 0) animated:YES]; //解决tableView分割线 ...

  4. 提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll

    新版本SQLITE,如果下载Precompiled Binaries版会出现提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll. 下载Prec ...

  5. LintCode "Heapify"

    My first try was, using partial sort to figure out numbers layer by layer in the heap.. it only fail ...

  6. 51nod1369 无穷印章

    有一个印章,其完全由线段构成.这些线段的线足够细可以忽略其宽度,就像数学上对线的定义一样,它们没有面积.现在给你一张巨大的白纸(10亿x10亿大小的纸,虽然这个纸很大,但是它的面积毕竟还是有限的),你 ...

  7. 关于windows下c/c++的rand()的一个测试

    ,,,}; ,-,,}; ,y=; ;t<<<;t++){ ; x+=xs[d];y+=ys[d]; 在(x,y)绘制一个点; } 根据rand()%4的值决定点的移动方向,生成图像 ...

  8. 【linux】之虚拟机的使用

    VMware常用的配置 1.虚拟机快照设置 2.虚拟机克隆 分为链接克隆和完整克隆 链接克隆不占用过大的资源,但是主机删除之后,克隆机无法正常使用 完整克隆,占用空间资源,和主机之间互不影响 一般常用 ...

  9. 免安装Oracle客户端使用PLSQL Developer 7/8 连接Oracle10/11g

    众所周知,Oralce的客户端几百兆太大,网上也有许多DIR的处理.这里的处理使用官方提供ORALCE工具包Instant Client Package! 下载地址:http://www.oracle ...

  10. 【MySQL】数据行长度的一些限制

    今天开发在导入数据的时候报一个错误: Row size too large. The maximum row size for the used table type, not counting BL ...