String一点小发现
今天面试官问了几个关于java内存方面的问题,其中有一个是关于内存重复使用的。突然想到java中String比较特殊的地方,根据自己的理解所以稍微记录一下以免遗忘。
对于下面这个小程序:
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1 = "123";
String s2 = "123";
String s3 = new String("123");
String s4 = new String("123");
System.out.println(s1 == s2); //true
System.out.println(s3 == s4); //false
}
- 执行s1 == s2时,返回的是true。
- 是因为在String源码中,String类的私有变量有两个,一个是char型数组,用来存放字符串本身;一个是hash,用来保存传入的字符串在内存中的哈希码;
- s1和s2都是local variable局部变量,都是存放在stack中,因此他们的哈希码是一样的,所以java在为s1, s2分配内存时,实际分配的是栈中同一块内存,所以结果返回true;
- 它实际是String.intern()方法起作用了。intern()方法是一个Native方法,作用是,如果字符串常量池中已经包含一个此String对象的字符串,则返回池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。
- 执行s3 == s4时,返回的是false。
- 是因为它们都是用的new关键字,新建的是Dynamic variable动态变量,java首先为s3,s4在stack上各分配一个指针地址,表示有两个动态变量声明了,然而他们实际存储的东西放在heap中。
- s3 == s4语句实际判断的是他们在heap中的地址,所以结果自然是false咯。

- java的内存存储机制:
- static, constant型的变量都存储在一些特殊的位置,一般在内存中从地址最低的地方开始使用;
- dynamic variable型的变量(即用new关键字生成的变量、对象)都存储在Heap中,他们存储的内容实际上是地址,地址指向的才是数据真正的存储地方,数据一般都放在栈中;
- heap紧跟在static、constant变量的后面,地址逐渐增大,可以从小地址向大地址动态增大;
- local variable型的变量都存储在stack中
- 为了不浪费内存空间又不与heap地址冲突,stack地址一般是从最大地址开始逐渐减小,方便heap和stack双方扩充。

String一点小发现的更多相关文章
- 关于PHP魔术方法__call的一点小发现
好久没有上博客园写文章了,今晚终于有点空了,就来写一下昨天的一点小发现. 我自己所知,C++,Java的面向对象都有多态的特点,而PHP没有,但PHP可以通过继承链方法的重写来实现多态的属性.而魔术方 ...
- 【自动化测试】robot framwork的一点小发现
我们在搭建完robotframwork框架并开始打开火狐浏览器的时候,总会碰到打不开浏览器的问题.这次,分享一个常见的小问题. 这个问题呢,是因为火狐的版本更新频繁,导致selenium的版本跟不上导 ...
- 【安全性测试】Android测试中的一点小发现
在执行某个项目中的APP测试发现的两个问题,自然也是提供参考,作为经验记录下来. 一.通过apk的xml文件获取到某项目APP的账号和密码 使用eclipsel或者drozer,获得apk的xml文件 ...
- 关于Datastage资料库的一点小发现
这里的资料库,指的是Datastage Metadata层,在Datastage7.5以后,需要在安装Datastage时安装一个数据库用于存放用户数据. 昨天领导要求安装Datastage集群/高可 ...
- 关于win8开发的一点小总结
我今天做画面的时候,发现了一点小问题. 我在xmal文件里面加了一个CheckBox控件,设置IsChecked属性为True,并添加了Checked事件.Checked事件里面有对另外一个TextB ...
- 【手记】小心在where中使用NEWID()的大坑 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题 【C#】组件分享:FormDragger窗体拖拽器 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
[手记]小心在where中使用NEWID()的大坑 这个表达式: ABS(CHECKSUM(NEWID())) % 3 --把GUID弄成正整数,然后取模 是随机返回0.1.2这三个数,不可能返回其它 ...
- HTML5版的String Avoider小游戏
HTML5版的String Avoider小游戏 http://www.newgrounds.com/portal/view/300760 蛮简单也蛮考验耐心,从游戏起始点移动鼠标到终点位置,鼠标移动 ...
- net core体系-web应用程序-4net core2.0大白话带你入门-8asp.net core 内置DI容器(DependencyInjection,控制翻转)的一点小理解
asp.net core 内置DI容器的一点小理解 DI容器本质上是一个工厂,负责提供向它请求的类型的实例. .net core内置了一个轻量级的DI容器,方便开发人员面向接口编程和依赖倒置(IO ...
- C与C++在形參的一点小差别
先看一下以下的代码: int fun(a,b) int a; int b; { return 10; } void main(int argc, char ** argv) { fun(10); re ...
随机推荐
- 在linux下的firefox中安装flashplayer
将 libflashplayer.so 复制进 ~/.mozilla/plugins/ 若目标目录不存在,请自行创建
- 【RoR win32】新rails运行后0.0.0.0:3000不能访问
在浏览器中使用127.0.0.1:3000来访问
- 【crunch bang】字体美化
中文字体美化是个很讨厌的事情,无数初学者在这里面浪费了无数时间,做了无数没有意义的事情.但这也是不得不做的,我把 Debian/Ubuntu 所需要的中文字体美化操作步骤详细记录在这里,希望能节约大家 ...
- android 学习随笔二十二(小结)
ADB进程 * adb指令 * adb install xxx.apk * adb uninstall 包名 * adb devices * adb start-server * adb kill-s ...
- ASP.NET MVC下的四种验证编程方式[续篇]【转】
在<ASP.NET MVC下的四种验证编程方式> 一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式(“手工验证”.“标注ValidationAttribute特性”.“ ...
- docker学习整理
1.安装 Docker 支持 CentOS6 及以后的版本 对于 CentOS6,可以使用 EPEL 库安装 Docker CentOS7 系统 CentOS-Extras 库中已带 Docker,可 ...
- Dynamics AX 2012 R2 Business Connector Error
6.0: AxCryptoClient - New encryption key created 6.0: Unable to InitializeSession. 6.0: No built-in ...
- 为博客启用MetaWeBlog API
最近想写一个博客系统,主要有以下几点功能. 能够使用Live Writer来发布.修改文章 使用MongoDB作为持久化 对于博客中的图片.CSS.JS文件,使用CDN加速 后期可加上Radis 使用 ...
- master-slave(主/从)模式
主从模式 一般来说用在数据库集群比较多,主要是实现读写分离.对于数据库应用而言基本上是读大于写,因此由 Master 服务器负责增.删.改操作,由 Slave 负责读操作(也就是 SELECT),Ma ...
- mongo 日记
分组代码片段 命令行代码: aggregate({$group:{_id:{A:'$A',B:'$B',C:'$C'}}}) 拿出唯一号有重复的数据: > db.aaaa.aggregate([ ...