String:字符串常量池详解
本文基于jdk8
使用双引号声明的字符串
使用双引号声明的字符串,先在常量池中查找。如果有相同的,就直接把引用返回;否则就在常量池中创建并返回引用
//因为用双引号声明的String对象会直接放在常量池中。 String s1 = "abc";//常量池中的引用 String s2 = "abc";//常量池中的引用 //使用双引号声明的字符串,先在常量池中查找, //如果有相同的,就直接把引用返回,如果没有就在常量池中创建并返回引用 System.out.println(s1 == s2);//true 123456
使用new关键字创建的字符串
采用new关键字新建一个字符串对象时,JVM首先在字符串池中查找有没有该字符串,如果有则在堆中创建对象返回堆中的引用;如果常量池中没有该字符串则先在常量池中创建字符串,之后在在堆中创建字符串对象,并返回堆中的引用。
//采用new关键字新建一个字符串对象时,JVM首先在字符串池中查找有没有"xyz"这个字符串对象, // 如果有,则不在池中再去创建"xyz"这个对象了,直接在堆中创建一个"xyz"字符串对象, // 然后将堆中的这个"xyz"对象的地址返回赋给引用s3, // 这样,s3就指向了堆中创建的这个"xyz"字符串对象; // 如果没有,则首先在字符串池中创建一个"xyz"字符串对象,然后再在堆中创建一个"xyz"字符串对象, // 然后将堆中这个"xyz"字符串对象的地址返回赋给s3引用, // 这样,s3指向了堆中创建的这个"xyz"字符串对象。s4则指向了堆中创建的另一个"xyz"字符串对象。 // s3 、s4是两个指向不同对象的引用,结果当然是false String s3 = new String("xyz");//在常量池中创建xyz,在堆中创建对象并返回引用 String s4 = new String("xyz");//在堆中创建对象并返回引用 System.out.println(s3 == s4);//false 12345678910111213
s.intern()的作用
如果常量池中没有该字符串,调用了该方法,会将常量池中开辟空间,里面保存堆中字符串的地址。
{ //在常量池中创建“1”字符串,并且在堆中创建字符串1对象,s1是堆中的引用 String s1 = new String("1"); String s3 = s1.intern(); //s3是常量池中的引用 String s2 = "1"; //s2是常量池中的引用 System.out.println(s1 == s2);//false System.out.println(s2 == s3);//true System.out.println(s1 == s3);//false //第二种情况 // 第一个new String("1")先在常量池中创建“1”,在堆中创建“1”对象。 // 第二个new String("1")因为常量池中已经有“1”了,常量池中就不创建了,在堆中创建“1”; // 因为用加号连接了所以在堆中还要创建“11”对象,s3是堆中的11对象 String s3 = new String("1") + new String("1"); // 常量池中没有11,先创建(并不是创建“11”,而是存储堆中的引用)再返回常量池中的引用。 String s5 = s3.intern(); String s4 = "11";//直接返回常量池的引用 System.out.println(s3 == s4);//true// s3指向的是堆中的11对象 String s3 = new String("1") + new String("1");// s5指向的常量池中的地址,该地址存的是堆中11对象的引用, String s5 = s3.intern(); // s4指向常量池中的地址 String s4 = "11"; // 因为常量池的保存的是堆中的引用,三个变量指向是一样的 System.out.println(s5 == s3);//true System.out.println(s5 == s4);//true System.out.println(s3 == s4);//true System.out.println("======================"); // String s6 = new String("go") +new String("od"); // String s7 = s6.intern(); // String s8 = "good"; // System.out.println(s6 == s7);//true // System.out.println(s7 == s8);//true // System.out.println(s6 == s8);//true String s1 = "Hello";//直接在常量池中创建“hello” //现在常量池中创建He,之后再堆中创建He //之后在常量池中创建llo //因为常量池中已经有hello了,所以不再常量池中创建了,直接在堆中创建hello; String s2 = new StringBuffer("He").append("llo").toString(); String s3 = s2.intern();//返回常量池中的引用。 System.out.println("s1 == s2? " + (s1 == s2));//false System.out.println("s1 == s3? " + (s1 == s3));//true String m = "hello,world"; String n = "hello,world"; String u = new String(m); String v = new String("hello,world"); System.out.println(m == u); //false m是常量池中的,u是堆中的,并不相等 System.out.println(u == v); //false u,v是堆中的不同对象,并不相等 // 发现原来是在JVM启动的时候调用了一些方法,在常量池中已经生成了"java"字符串常量, // String s2 = new String("ja") + new String("va"); // String s3 = s2.intern(); // String s4 = "java"; // System.out.println(s2 == s3);//false // System.out.println(s3 == s4);//true }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273相关知识
字符串
字符串String的+和+=及循环操作String的原理
java 中equals和==的区别
Java 字符串格式化详解
Python变量和数据类型Number、String、转义字符、字符串格式化
2021年1月学考选考技术知识点之字符串问题
性能调优: df中的string wordcount
字符串 (C++/CX)
字符串(C# 编程指南)
字符串基础(C# 编程指南)
网址: String:字符串常量池详解 https://www.huajiangbk.com/newsview1250726.html
上一篇: 摆盘青菜花 |
下一篇: 常见青菜的种类有哪些? |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039