java中的字符串常量池_java字符串常量池
字符串常量池SCP
jdk1.6是放在永久代(8中叫方法区或叫元空间)中;
jdk1.7+中,字符串常量池放入了堆中,注意运行时常量依然存放在方法区,例如,Integer a = 40;Java在编译的时候会直接将代码封装成Integer a =Integer.valueOf(40);从而使用常量池中的对象。
字符串常量池中的元素是唯一的
jdk1.7+为了节省内存,对象的真实数据实际上只会有一份,要么在scp中,要么在scp外的堆中,然后scp中引用堆中的地址
intern函数
查询字符串常量池中是否存在当前字符串;
如果字符串常量池中存在此字符串,返回常量池中的字符串的地址;如果常量池中不存在,在常量池中添加此字符串,并返回地址
创建字符串到字符串常量池
String s0 = "abc"; 这种方式创建的字符串直接存放到字符串常量池中
通过new的方式创建的字符串,需要调用intern()方法,就可以存放到字符串常量池中
创建对象个数
可以通过字节码文件查看
String s2 = new String("abc");
上面这行代码实际创建了2个对象,一个是字符串常量池外部的堆空间的abc,另一个是常量池中引用堆空间中abc的地址,s2本体是存放在scp外的堆中,常量池引用了这个地址
String s5 = new String("a") + new String("b") + new String("c");
上面这行代码,字符串常量池中没有存放"abc",会单独存放"a","b","c";
变量之间使用+号,实际会创建一个StringBuilder,然后调用append(),最后调用toString()方法
创建方式
使用字面量(引号)创建
String s1= "abc";
String s2= "abc";
当我们第一次执行String s1 =“abc”时,JVM将在常量池中创建一个新对象,s1将引用该对象,即“abc”。
当我们第二次执行String s2 =“abc”时,JVM将检查字符串常量池中是否存在任何值为“abc”的对象。截至现在是的,我们已经在“字符串常量”池中存在“abc”,因此它不会创建新对象,只是s2引用变量将指向现有的“abc”对象。
使用new关键字
String s2 = new String("abc");
jvm会第一步检查常量池是否有"abc", 发现没有,创建一个新对象在常量池中.
然后因为有new关键词,所以会在堆中创建对象,然后将这个对象的地址引用返回
组合创建
String st1 ="abc";
String st2 = new String("abc");
当我们执行String st1 ="abc";时,JVM将在字符串常量池中创建一个对象
执行第二步的时候,JVM将检查字符串常量池中是否有任何可用的名称为“abc”的对象,现在是有,我们已经在字符串常量池中使用了“abc”,因此JVM不会在字符串常量池中创建任何对象。
因为有new关键词,它将在堆中创建一个对象,st2将指向该对象。
intern验证
以下代码运行环境为jdk1.8
情景一
String str = "aa";
String str2 = new String("aa");
System.out.println(str == str2); //false
String str3 = str2.intern();
System.out.println(str == str3); //true
String str = “aa”;在scp创建了一个对象"aa",
而String str2 = new String(“aa”);这里其实有两步
第一步java去scp找"aa",发现scp有"aa"
第二步,在堆中创建对象.所以两者地址不一样,str == str2 为false.
第二个,在经过 String str3 = str2.intern();后,intern发现scp已经有"aa"了, 所以直接将scp的地址返回给str3, 所以str == str3都是scp的地址,所以为true.
情景二
String s = new String("a") + new String("b");
String s1 = "ab" + "cd";
String s2 = s.intern();
String s3 = "ab";
System.out.println(s == s2); //true
System.out.println(s3 == s2);//true
这是因为第一行代码, 据上面所知,不管"a"和"b",只会在堆中创建"ab"对象
第二行代码,我们用两个声明字符串相加,可知jvm会优化,直接在scp中创建"abcd"
第三行代码,s调用intern方法,发现scp没有"ab",将s在堆中的引用地址给s2
第四行代码,java先去scp找"ab",发现有,直接将其地址返回给s3
所以s指向堆中的地址,s2也是这个地址,所以相同. s3==s2同理,相同
情景三
如果将String s3 = "ab"放到前面
String s = new String("a") + new String("b");
String s1 = "ab" + "cd";
String s3 = "ab";
String s2 = s.intern();
System.out.println(s == s2); //false
System.out.println(s3 == s2); //true
第一行代码和第二行代码如上
第三行代码,java发现scp没有"ab",在scp创建新对象,然后返回地址给s3
第四行代码,s调用intern方法,发现scp有"ab",将s在scp中的引用地址给s2
所以s是堆中的地址,s2和s3是scp的地址,所以结果是false和true
情景四
这次不调整代码顺序,而是将"ab" + “cd”,两个声明式相加,变成其中一个是变量
String s = new String("a") + new String("b");
String s1 = "ab" + s;
String s2 = s.intern();
String s3 = "ab";
System.out.println(s == s2); //false
System.out.println(s3 == s2); //true
因为s1不再是两个声明式相加,编译器无法得知结果,所以将String s1 = "ab" + s变成:String var = "ab";String s1 = var + s;
所以"ab"会在scp中,s2拿到的也会是var的地址,所以s == s2 为false
java中的字符串常量池_java字符串常量池相关推荐
- java中sql 语句格式转换_Java字符串转Sql语句In格式工具方法
/** * 工具-字符串-转换Sql查询IN中使用的格式 * 效果:a,b==>'a','b' * @param str * @return */ public String strToDbin ...
- java测试字符串的编码_Java字符串测验
java测试字符串的编码 Welcome to Java String Quiz. String is one of the most important classes in Java. If yo ...
- Java中获得了方法名称的字符串,怎么样调用该方法
问题: Java中获得了方法名称的字符串,怎么样调用该方法 如果我有以下两个变量 Object obj; String methodName = "getName"; 在不知道ob ...
- java split 字符串作为分隔符_Java 字符串分隔 split
Java中的我们可以利用 split 方法(Java.lang.string.split)把字符串按照指定的分割符进行分割,然后返回字符串数组,下面是string.split的用法实例及注意事项. s ...
- java反转函数_在JAVA中,下列哪个函数可用于字符串的反转?
在JAVA中,下列哪个函数可用于字符串的反转? 更多相关问题 很多危机是无法准确预测的,必须为危机做好准备,包括().通信计划以及重要关系的建立等. (A) 危 幼儿园科技小制作可分为模型类.动力类. ...
- JAVA中如何将大数字或字符串放进数组
JAVA中如何将大数字或字符串放进数组 在JAVA学习过程中字符串.数组.数字之间的 的转换经常用到,记录一些非常基础的转换. 1.将数字转换为字符串:String str = String.valu ...
- Java中[xxx:xxx,aaa:aaa]格式字符串解析
Java中[xxx:xxx,aaa:aaa]格式字符串解析 String str = "[name:张三,age:18,phone:15888887777,email:15888887777 ...
- Java中,那些关于String和字符串常量池你不得不知道的东西
老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xy ...
- java中String类是什么_Java中字符串的学习(一)String类的概述及常见方法使用
转载请注明出处http://www.cnblogs.com/devtrees/p/4347079.html (拓展:Api:编程语言对外给我们提供的应用程序接口.) 一.概述: 我们平时上网发帖,帖子 ...
最新文章
- 职校中的计算机学的是什么,职校计算机专业主要学什么课
- 阅读Book: MultiObjective using Evolutionary Algorithms (3) -----关于pareto最优的各种概念
- Struts1.x的使用
- 文本文件与二进制文件及编码关系
- boost::histogram::axis::transform用法的测试程序
- oracle normal bitmap,深入解析Oracle ASSM结构之Level 1 Bitmap Block
- 【工作经验分享】不会真有人觉得mybatis很难学吧
- nginx php上传配置
- 全国区块链信息服务备案超千个
- android 简书饿了么,分析饿了么详情页布局
- Android jobb 工具使用详解
- 【公司邮箱如何申请】怎么写加密邮件,企业邮箱支持吗?
- 如何解决上班下午3:00发困的事情
- 扁平和树形结构的几种互转
- 达梦DM数据库—线上培训学习简记
- nextcloud+onlyoffice 打开wps方法,亲测方案。
- 指针笔试题详细介绍,让你不再惧怕指针【c语言】
- 机器人有同理心吗?情感AI的可用性有多少?
- 学习理发去哪里_学美发去哪里学习好
- Windows Server 2012 R2 或Windows Server 2019 镜像SXS下载,解决,net3.5无法安装问题
热门文章
- 智能手环core日志获取-兔盯云
- AWS中IGW,NAT GW以及Egress-only IGW的概念和区别
- 《汇编语言程序设计》(双语)上机指导
- JAVA设计模式笔记(简单工厂模式)
- javaweb-39:文件上传及拓展鸡汤
- 软考中项第三章 信息系统集成专业知识
- 在HTML中 怎么一张图片上在放一张图片,css sprites把很多小图集成在一张图片上...
- 2023前端面试题集(持续更新中~),祝大家早日拿到心仪offer
- 简历上的项目经历怎么写 ?这 3 条原则不可忽视 !...
- Linux中如何安装特定的gcc版本