💗推荐阅读文章💗
- 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》
- 🌺MySQL系列🌺👉2️⃣《MySQL系列教程》
- 🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》
- 🌻SSM框架系列🌻👉4️⃣《SSM框架系列教程》
🎉本博客知识点收录于🎉👉🚀《JavaSE系列教程》🚀—>✈️07【Java核心API-01】✈️
文章目录
- 6.3 常量池
- 6.3.1 String字符串的比较
- 6.3.2 字符串的创建
- 1)例1:
- 2)例1:
- 3)例2:
- 4)例3:
- 6.3.3 字符串的比较练习
- 6.3.4 intern方法
6.3 常量池
常量池也是JVM中的一块内存区域,在JDK1.6及以前,这时的方法区也被成为永久代;常量池是存储在方法区的,在JDK1.7之后,常量池被划分到了堆内存。
6.3.1 String字符串的比较
创建字符串的方式有很多种,不同的方式创建的字符串在内存中的表现形式是不一样的;因此我们在使用字符串做==
比较时需要格外注意;因为==
比较的是两个对象的内存地址值;
package com.dfbz.demo01;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo06 {public static void main(String[] args) {// 存储在常量池String s1 = "abc";// new的东西都存储在堆内存String s2 = new String("abc");// new的东西都存储在堆内存String s3 = new String("abc");System.out.println(s1); // abcSystem.out.println(s2); // abcSystem.out.println(s3); // abcSystem.out.println(s1 == s2); // falseSystem.out.println(s2 == s3); // false}
}
内存图解:
6.3.2 字符串的创建
我们之前就介绍过,String是一个不可变的字符序列,即字符串一旦创建就是不可变的;但我们在操作字符串时,字符串好像是可以拼接改变的,这究竟是怎么回事呢?
下列代码产生了几个字符串?
1)例1:
String s1="1";
s1="2";
答:2个,“1”、“2”;
2)例1:
String s1 = "10" + "1";
答:3个,“10”、“1”、“101”;并且3个都存储在常量池
3)例2:
String s1 = new String("abc");
答:2个,一个"abc"存储在常量池,另一个"abc"存储在堆内存;s1保存着堆内存中"abc"的引用;
4)例3:
String s1 = "10";
s1 += "1"; // s1=s1+"1";
- 答:3个,“10”、"1"存储在常量池,"101"存储在堆内存,s1保存着堆内存中"101"的引用;
tips:任何与变量相加的字符串都会产生一个新字符串,存储在堆内存;
总结:字符串一旦创建了就不能改变,如果改变了那也是创建了一个新的字符串将其返回,再也不是原来那个字符串了;
6.3.3 字符串的比较练习
在字符串拼接时,只要是和变量相加,其结果都会产生一个新的字符串;
观察如下代码:
int i = 1;
String s1 = "10" + i;
String s2 = "10" + i;
System.out.println(s1 == s2); // false
将变量换成常量:
String s1 = "10" + 1;
String s2 = "10" + 1;
System.out.println(s1 == s2); // true
- 练习题:
package com.dfbz.demo01;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo08 {public static void main(String[] args) {String s1 = "abc";String s2 = "abc";String s3 = "ab" + "c";String s4 = "ab" + new String("c");String s5 = new String("abc");String s6 = "a";String s7 = "bc";String s8 = s6 + s7;System.out.println(s1 == s2); // true(都存储在常量池)System.out.println(s1 == s3); // true(常量相加,生成的值也是在常量池,保留常量池中的引用)System.out.println(s1 == s4); // false(只要是和变量相加,都会new出一份新的)System.out.println(s1 == s8); // false(只要是和变量相加,都会new出一份新的)System.out.println(s4 == s5); // false}
}
6.3.4 intern方法
public String intern()
:当调用intern方法时,如果常量池已经包含与equals()方法确定相当的字符串时(比较的是字符串内容而不是地址值),则返回来自常量池的字符串,否则将此字符串添加到常量池中并返回;
示例代码:
package com.dfbz.demo01;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo09 {public static void main(String[] args) {String s1 = "1" + new String("1");// 查看常量池是否有"11"这个字符串,如果没有,则将"11"存入常量池,并返回常量池的地址String s2 = s1.intern();String s3 = "11";System.out.println(s2 == s3); // true}
}
图解: