本文知识点

这一块的知识点,一直都是最为混乱的,网上很多博客有的都自相矛盾,因此,这一块需要深入学习,本文以JDK11为基础,尽量参考官方文档

  • 静态常量池

  • 运行时常量池及字符串的引用

  • 各种String语句变量的地址

参考文档:

https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.1

静态常量池

静态常量池也常常称做为class常量池,是每个.class文件都有的,如测试代码如下:

public class Main {    public static void main(String[] args) {         String s = "java技术大本营";                System.out.println(s);             } }

我们在.class文件目录执行javap -v Main.class 可以看到如下图所示常量池信息:

如上图画线部分的Constant pool,就是静态常量池/class常量池, 在下面的内容中, 我们可以看到, 和我们需要找的java技术大本营来对比,有两行是相关的

#2=String  #23  //java技术大本营

#23=Utf8 java技术大本营

#23 = Utf8 java技术大本营 代表 #23这个位置存的是Utf-8编码的字符串

#2=String #23 //java技术大本营 代码#2 这个位置是字符串常量,字符串的值指向#23这个位置

运行时常量池

运行时常量池是方法区的一部分,每一个类(注意不是实例)都拥有自己的运行时常量池.这里我们先看字符串常量,测试代码如下:

public class TestObject {    private String s  = "java技术大本营";}public class Main {    public static void main(String[] args) {         TestObject t1 = new TestObject();            TestObject t2 = new TestObject();            System.out.println(t1);       }}

如上代码所示,在运行到System.out.println(t1)时,堆里应该有两个TestObject实例.然后我们需要看这两个实例中的s是不是都指向同一个位置, 打开HSDB可看到如下信息:

如上图所示,可以看到两个不同的实例引用的是同一个字符串.

testObject实例存着s这个字符串的地址引用. s里面存着'java技术大本营'的byte的引用.s 在字符串常量池中.

各种String语句变量的地址

以前遇到这种问题只能各种猜,现在可以顺着静态常量池,运行时常量池一步步的看下去,运行代码如下:

public static void main(String[] args) {    String s1 = "java技术大本营";    String s2 = "java技术大本营";    String s3 = "凑"+"心";    String s4 = new String("凑心");    String s5 = new String("Drift north");    //true        System.out.println(s1==s2);    // false        System.out.println(s3==s4);    String s6 = s4.intern();        // true        System.out.println(s3==s6);}

运行结果我已经放上面了,这里只要注意以下知识点,就不难判断出来

  • 只有new才往堆里面放

  • == 比较的是地址

  • intern()的作用

  • s3 = "凑"+"心"; 这个在编译的时候会直接变成"凑心"

这里我们直接通过HSDB来看各个字段的地址,断点先打在String s6 = s4.intern()这里

如上图所示,我们可以得到如下5个地址.通过inspect,我们可以做如下对应:

0x0000000110a197f8 // Dirft North

0x0000000110a197d8 //凑心

0x0000000110a19798 //凑心

0x0000000110a19748 //java技术大本营

0x0000000110a19748 //java技术大本营

这里要注意第二条和第三条,都是凑心,但是地址却不一样.常量池是肯定只有一条的,然后我们先detach , 然后断点往下走一行,执行一下intern()

可以看到在原来的基础上,新增了一个s6,地址是798. 就和我们上面的第三条的地址是一样的了. 也就是执行了intern()之后, 会看常量池有没有, 有就返回常量池的地址引用.

总结

这一块知识点的延伸还有很多,比如创建了几个String对象, 比如hsdb里面还可以用js去调试等等. 比起死记硬背,还是更推荐大家这样调试着去学习!

更多文章欢迎点击查看原文.

读取字符串字符时出错_JVM | 运行时常量池和字符串常量池及intern()相关推荐

  1. vc++编译时没有问题,运行时出现runtime error的解决办法

    最近我遇到一个问题就是vc++编译时没有问题,运行时出现runtime error 就是这个提示! 怎么解决呢?很简单,仔细检查你的代码就行了,出现这种情况一般都是代码有误,有人会说那为什么编译没问题 ...

  2. 编译时异常与运行时异常

    在实际开发中,经常会在程序编译时产生一些异常,必须要对这些异常进行处理,这种异常称为编译时异常,也称为checked异常.另外,还有一种异常是在程序运行时产生的,这种异常即使不编写异常处理代码,依然可 ...

  3. Java-编译时类型与运行时类型

    编译时类型与运行时类型 在Java编程语言中的许多对象都是存在具有父子类型关系的.因为子类也可以理解成另类的一种父类(例如小明是一个学生类 但是他也可以是一个人类)因此在java中是允许父类引用类型指 ...

  4. Android 12.0首次开机默认授予app运行时权限(去掉运行时授权弹窗)

    目录 1.概述 2.首次开机默认授予app运行时权限(去掉运行时授权弹窗)的解决方案的核心类

  5. #汇编语言字符串的输出(dosbox运行时输出乱码问题解决)

    #汇编语言字符串的输出 dosbox运行时输出乱码,经过检查发现在定义字符串时忘记在后面加上$字符 代码一· ;This is the structure of a main module using ...

  6. 运行时错误7内存溢出_JVM运行时内存数据区域

    阅读本文大概需要5分钟 作者:AI乔治出处:https://my.oschina.net/u/3611782/blog/4530512 1 讨论背景 周志明老师写的<深入理解Java虚拟机> ...

  7. flash cs3 pro 写了脚本说java运行环境出错,Flash CS3动作面板打开出错[Java运行时环境初始化时出现错误,你可能需要重......

    为了携带和使用方便,大多数人会选择使用软件的精简版,首先要感谢那些制作精简版软件的作者,因为这类软件一般不用安装,直接就能使用,而且体积一般只有 100MB左右.不过,正因为精简版精简了很多被认为是& ...

  8. 解决:flash cs5运行时出现“java运行时环境初始化时出现错误,你可能需要重装Flash”

    我安装时遇到这个问题,并已成功解决. 解决办法: 确定C:/Documents and Settings/All Users/Application Data/Adobe/CS5/jre下有相关jav ...

  9. 安装mysql配置时出错_mysql安装时出现各种常见问题的解决方法

    小编为大家整理许多mysql安装时出现各种常见问题的解决方法,供大家参考,具体内容如下 问题一: 当各位在安装.重装时出现could not start the service mysql error ...

最新文章

  1. Unity3D常用代码总结
  2. display:inline、block、inline-block的区别
  3. NVIDIA Jetson TK1学习与开发(八):图文详解OpenGL在Jetson TK1上的安装和使用
  4. 符号引用(typeglob,别名)与全局变量的修改
  5. mybatisPlus的分页查询
  6. RIP RETE时间获得PHREAKY
  7. [其它] - 为什么中国的程序员技术偏低
  8. (王道408考研数据结构)第五章树-第三节3:线索二叉树
  9. 枚举算法:试统计正整数n的阶层n!=1*2*...*n尾部连续零的个数。
  10. idea中使用github
  11. 贪心算法(各种贪心题目)
  12. MarkDown(七)——LaTeX数学公式符号标记
  13. 如何在scope图中标注_电机学习笔记: 变压器初级(原边)和次级(副边)的感应电动势、电压方向如何标注?...
  14. 计算机维护系统Win8PE,U盘启动计算机维护系统
  15. 2020年下系统集成项目管理工程师真题基础知识+解析1/3
  16. php钱兆楼,PHP动态网站开发实例教程(第2版)
  17. oracle18c18.3,oracle 18c客户端提供下载了
  18. 计算机硬盘模式,硬盘三种模式的含义-电脑自学网
  19. Ajax的网络响应时间
  20. 什么是PCB加工中树脂塞孔工艺?

热门文章

  1. 汇编指令mrs_汇编指令 - Mrs.kang - 博客园
  2. 下面哪个字段是http请求中必须具备的_HTTP协议及其工作原理介绍
  3. iOS 11开发教程(十五)iOS11应用视图的位置和大小
  4. java中utilities类_servletutilities属于哪个java包
  5. vue 根据后台数据 判断显示_【开源】el-admin 后台管理系统,v1.9 发布
  6. linux ll一页一页,Linux使用技巧33则
  7. EEGNet: 神经网络应用于脑电信号
  8. pyglet wave.Error: file does not start with RIFF id
  9. 魔改CNN揭秘宇宙大爆炸:物理学的核心是对称性
  10. 魔改GPT自动写网文,速度一秒十字,还能给太监作品无限续更 | 开源