专业编程基础技术教程

网站首页 > 基础教程 正文

程序员每日一题-你不知道的Integer

ccvgpt 2024-08-06 12:35:03 基础教程 10 ℃


解析:

这道题其实本意是靠int,Integer,String三种数据类型的值在jvm中的存放位置。

程序员每日一题-你不知道的Integer

这里面牵涉到一个知识点,jvm里面的常量池。


图中可以看到有一个字符串常量池,和一个运行时常量池

运行时常量池:?

Java语言并不要求常量一定只能在编译期产生,运行期间也可能产生新的常量,这些常量被放在运行时常量池中。

类加载后,常量池中的数据会在运行时常量池中存放

这里所说的常量包括:基本类型包装类(包装类不管浮点型,整形只会管-128到127)和String(也可以通过String.intern()方法可以强制将String放入常量池)

字符串常量池:?

HotSpot VM里,记录interned string的一个全局表叫做StringTable,它本质上就是个HashSet<String>。注意它只存储对java.lang.String实例的引用,而不存储String对象的内容?

jdk 1.7后,移除了方法区,运行时常量池和字符串常量池都在堆中。


这儿我们讨论运行时常量池。

选项分析

A:字符串在java程序中被大量使用,为了避免每次都创建相同的字符串对象及内存分配,JVM内部对字符串对象的创建做了一定的优化,所以A选项里面“hello"在常量池中只有一份,但是有两个引用(变量名a,b在字符串常量池中)同时指向它,所以A选项里面,a和b具有相同的内存引用地址

B:这个简单了,两个Integer类型,都直接用=把地址引用给b了,肯定指向同一地址

C:这边注意一个知识点,非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同,所以C不是同一地址,但是a==b的结果确实true,这是为啥呢?

因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较

D:理由同上,非new生成的Integer变量指向的是java常量池中的对象,int a也在常量池中,所以他们的内存地址是一样的


最后留一个题:

Integer a =128;

Integer b =128;

System.out.println(a==b);

友情提醒:java在编译Integer b =128时,会翻译成为Integer i = Integer.valueOf(128),大家可以看看Integer.valueOf的源码,也是对上面"非new生成的Integer变量指向的是java常量池中的对象"知识点的补充

最近发表
标签列表