A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 创造命运 中级黑马   /  2014-4-21 14:39  /  1684 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 创造命运 于 2014-4-21 18:49 编辑

刚看张老师的高新技术视频时,其中提到了享元模式:如果有很多很小的对象,他们有很多相同的属性,那么我们就可以把他们变成一个对象。另外将其他不同的内容变成这个对象外部的属性,以方法的参数的形式传入。java中引入了一个“整型常量池”,存储在方法区中,该常量池只存储“-128~127”之间的数据。对于在-128~127范围类的整数,在装箱的时候变成同一个整数。
比如说:
Integer a = 10;
Integer b = 10;
equals(a==b);时结果是true。就是说即使a和b的值都是同new Integer()产生的,但是他们是同一个对象。
这里运用到了享元模式。

对于字符串常量池:
String s1 = new String("abc");
String s2 = new String("abc");
equals(s1 == s2);时结果是false。我们都知道s1与s2是不同的对象,至于字符串"abc",在堆内存里会有两个,在字符串常量池里也会有一个。

这里我想知道的是:
1、字符串常量池与整型常量池有哪些不同的地方?除了一个存放字符串,一个存放整数之外。
2、为什么Integer a = 10;不会像字符串那样在堆内存里也创建一个对象呢?
3、字符串常量池有没有运用到享元模式?根据我提到的第二个问题,似乎可以推断字符串常量池没有运用到享元模式,是吗?
4、整型常量池又是以何种方式存在的?以字符串常量池为例,String s = "abc";程序运行到该语句时,会到字符串常量池里去找"abc",如果找到,就将该字符串赋值给变量s;如果没有找到,那么就会先在常量池里创建一个"abc"字符串常量,再赋值给变量s。那么语句:Integer a = 10;是不是以类似的方式来给变量b赋值的呢?

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

2 个回复

倒序浏览
你对于==这个符号的理解好像有点偏差吧               
int a = new Integer(10);
int b = new Integer(10);
System.out.println(a==b);//true

int x = new Integer(200);               
int y = new Integer(200);
System.out.println(x==y);//true

Integer c = 100;
Integer d = 100;
System.out.println(c==d);//true

Integer e = 200;
Integer f = 200;
System.out.println(e==f);//false
要注意,在int类型的比较中,==这个符号作为运算符是用来对比两个int类的值的大小差别的。
而在引用型对象中,==这个符号的作用则是用来比较内存地址是否相同的。
你这里的第一个ab都是int类,无论数值等于多少都是相等的,不存在引用常量变量池的问题。
String s1 = new String("abc");
String s2 = new String("abc");
equals(s1 == s2);时结果是false。我们都知道s1与s2是不同的对象,至于字符串"abc",在堆内存里会有两个,在字符串常量池里也会有一个。
这里是在堆内存中建立了两个指向字符串常量池的引用。两个引用的内存地址不同,自然用==号判断不会相等。
1、字符串常量池与整型常量池有哪些不同的地方?除了一个存放字符串,一个存放整数之外。
我记得java中的常量池其实是一个。字符串和整形都放在里面。

2、为什么int a = Integer(10);不会像字符串那样在堆内存里也创建一个对象呢?
int a,你已经把这个变量的类型变为基础数据类型了……相当于你在堆内存中创造了一个int,int的值和integer(10)一样都是10

3、字符串常量池有没有运用到享元模式?根据我提到的第二个问题,似乎可以推断字符串常量池没有运用到享元模式,是吗?
//s1,s2分别位于堆中不同空间
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1==s2);//输出false
//s3,s4位于池中同一空间
String s3="hello" String s4="hello";
System.out.println(s3==s4);//输出true
}
}
用new String()创建的字符串不是常量,不能在编译期就确定,所以new String()创建的字符串不放入常量池中,他们有自己的地址空间。


4、整型常量池又是以何种方式存在的?以字符串常量池为例,String s = "abc";程序运行到该语句时,会到字符串常量池里去找"abc",如果找到,就将该字符串赋值给变量s;如果没有找到,那么就会先在常量池里创建一个"abc"字符串常量,再赋值给变量s。那么语句:int b = new Integer(10);是不是以类似的方式来给变量b赋值的呢?

String 对象(内存)的不变性机制会使修改String字符串时,产生大量的对象,因为每次改变字符串,都会生成一个新的String。 java 为了更有效的使用内存,常量池在编译期遇见String 字符串时,它会检查该池内是否已经存在相同的String 字符串,如果找到,就把新变量的引用指向现有的字符串对象,不创建任何新的String 常量对象,没找到再创建新的。所以对一个字符串对象的任何修改,都会产生一个新的字符串对象,原来的依然存在,等待垃圾回收。
回复 使用道具 举报
kuroro自走核炮 发表于 2014-4-21 18:02
你对于==这个符号的理解好像有点偏差吧               
int a = new Integer(10);
int b = new Integer(10);

谢谢啦。理解了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马