当前位置: 首页 > news >正文

java常量池

java常量池技术  
java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多时间。常量池其实也就是一个内存空间,常量池存在于方法区中。
 
 
JVM的编译器将源程序编译成class文件后,会用一部分字节分类存储这些粗体代码。而这些字节我们就称为常量池。其中包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s ="java"这种申明方式;对于String s = "java",在编译成.class时能够识别为同一字符串的,自动优化成常量,所以如果有多个字符串"java",则它们都会引用自同一String对象。也就是说String s = "java" 其中"java"值在JAVA程序编译期就确定下来了的。(大家可以用UE编辑器或其它文本编辑工具在打开class文件后的字节码文件中看到这个java值)。这个java存在在常量池中。注意:常量池只存储文字字符串值,不存储符号引用。
 
而在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象.String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回一个引用,没有则添加自己的字符串进入常量池,注意:只是字符串部分。所以这时会存在2份拷贝,常量池的部分被String类私有并管理,自己的那份按对象生命周期继续使用。String s = new String("java");语句,到底创建了几个对象呢?  "java"本身就是常量池中的一个对象,而在运行时执行new String()时,将常量池中的对象复制一份放到堆中,并且把堆中的这个对象的引用交给s持有。所以这条语句就创建了2个String对象。
 
 
String类也是java中用得多的类,同样为了创建String对象的方便,也实现了常量池的技术。
测试代码如下:
public class Test{
public static void main(String[] args){
//s1,s2分别位于堆中不同空间
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1==s2);//输出false
//s3,s4位于池中同一空间
String s3="hello" Strings4="hello";
System.out.println(s3==s4);//输出true
}
}
用new String()创建的字符串不是常量,不能在编译期就确定,所以new String()创建的字符串不放入常量池中,他们有自己的地址空间。
String 对象(内存)的不变性机制会使修改String字符串时,产生大量的对象,因为每次改变字符串,都会生成一个新的String。 java 为了更有效的使用内存,常量池在编译期遇见String 字符串时,它会检查该池内是否已经存在相同的String 字符串,如果找到,就把新变量的引用指向现有的字符串对象,不创建任何新的String 常量对象,没找到再创建新的。所以对一个字符串对象的任何修改,都会产生一个新的字符串对象,原来的依然存在,等待垃圾回收。
代码:
String a = “test”;
String b = “test”;
String b = b+"java";
a,b同时指向常量池中的常量值"text",b=b+"java"之后,b原先指向一个常量,内容为"test”,通过对b进行+"java"操作后,b之前所指向的那个值没有改变,但此时b不指向原来那个变量值了,而指向了另一个String变量,内容为”text java“。原来那个变量还存在于内存之中,只是b这个变量不再指向它了。
 
 
八种基本类型的包装类和对象池  java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用常量池
Integer a = new Integer(128);
Integer b = new Integer(128);
这个时候再问你,输出结果是什么?你就知道是false了。如果把这个数换成127,再执行:
Integer a = 127;
Integer b = 127;
System.out.println(a == b);
结果就是:true
进行对象比较时最好还是使用equals,便于按照自己的目的进行控制。这里引出equals()和==,equals比较的是字符串字面值即比较内容,==比较引用。

转载于:https://www.cnblogs.com/dapeng111/p/3530542.html

相关文章:

  • 【iCore2 模块相关资料】发布模块DEMO 代码包,目前支持 iM_TFT30、 iM_LAN和 iM_RGB 三个模块...
  • 【基础】Oracle 表空间和数据文件
  • poj1195
  • PHP Install in IIS
  • mongoDB研究笔记:复制集故障转移机制
  • 网络资源收集
  • (顺序)容器的好伴侣 --- 容器适配器
  • javascript实现自动关闭的alert对话框
  • ASP.NET中上传图片检测其是否为真实的图片 防范病毒上传至服务器
  • cmd命令行中的errorlevel和延迟赋值
  • 我的项目经理2
  • iOS 开发小常识 开发笔记
  • 程序员修炼之道(一)
  • DevExpress.XtraEditors.TextEdit 设为密码输入框
  • 层次遍历二叉树(编程之美3.10)
  • [译] 怎样写一个基础的编译器
  • 【附node操作实例】redis简明入门系列—字符串类型
  • angular2 简述
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • HTTP中的ETag在移动客户端的应用
  • java中的hashCode
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Solarized Scheme
  • XML已死 ?
  • 百度地图API标注+时间轴组件
  • 从零搭建Koa2 Server
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 力扣(LeetCode)21
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 前端自动化解决方案
  • 使用Gradle第一次构建Java程序
  • 我从编程教室毕业
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • #Lua:Lua调用C++生成的DLL库
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (11)MATLAB PCA+SVM 人脸识别
  • (a /b)*c的值
  • (一)Dubbo快速入门、介绍、使用
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)重识new
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net Remoting常用部署结构
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [Angular] 笔记 7:模块
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [BJDCTF 2020]easy_md5
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]
  • [BZOJ1089][SCOI2003]严格n元树(递推+高精度)