String知识
# String知识
# 面试题
# Java字符串常量池
- Demo--考题+code
public class StringPool58Demo {
public static void main(String[] args) {
String str1 = new StringBuilder("58").append("tongcheng").toString();
System.out.println(str1);//58tongcheng
System.out.println(str1.intern());//58tongcheng
System.out.println(str1.intern() == str1);//true
System.out.println();
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2);//java
System.out.println(str2.intern());//java
System.out.println(str2.intern() == str2);//false
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
理解
- intern()方法
- 源码+解释
- 周志明《深入理解java虚拟机》2.4.3 方法区和运行时常量池溢出
- 由于运行时常量池是方法区的一部分,所以这两个区域的溢出测试可以放到一起进行。前面曾经提到HotSpot从JDK7开始逐步“去永久代”的计划,并在JDK8中完全使用元空间来代替永久代的背景故事,在此我们就以测试代码来观察一下,使用“永久代”还是“元空间”来实现方法区,对程序有什么实际的影响。
- String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。在JDK6或更早之前的HotSpot虚拟机中,常量池都是分配在永久代中,我们可以通过-XX:PermSize和-XX:MaxPermSize限制永久代的大小,即可间接限制其中常量池的容量
- 周志明《深入理解java虚拟机》2.4.3 方法区和运行时常量池溢出
- 源码+解释
- why?
- 按照代码的结果,java字符串答案为false,必然是两个不同的java,那么另外一个java字符串如何加载进来的?
- 为什么?
- 有一个初始化的java字符串(JDK出娘胎自带)在加载sun.misc.Version这个类的时候进入常量池
- OpenJDK8底层源码说明
- 递推步骤
- System代码分析
- System
- initializeSystemClass
- Version
- 类加载器和rt.jar
- 根加载器提前部署加载rt.jar
- OpenJDK8源码
- http://openjdk.java.net/ (opens new window)
- openjdk8\jdk\src\share\classes\sun\misc
- System代码分析
- 总结
- 递推步骤
- intern()方法
考查点
- intern()方法,判断true/false
- 是否读过经典JVM书籍--《深入理解java虚拟机》原题
编辑 (opens new window)
上次更新: 2024/05/24, 11:36:46