String常量池如何理解?面试一般会问吗?

IT资讯i


String常量池问题,答主根据自己的理解来简单说说吧!

为什么需要有String 的常量池

  • 原因其实就是因为String类是final修饰的,被final修饰的类各位小伙伴应该都知道是不能被基础的,也就是说创建String类型的变量赋值,在从新给它赋值实际上在内存中是会再次开辟空间来存储这个值。那么String类型和其它的引用类型一样创建会消耗很大内存空间,从而会影响到程序的性能。
  • 所以jvm为了节约资源,给String开辟了一个字符串常量池,那么每次要创建新的Strig你对象的时候都会到字符串常量池中先去看看有没有这个值,有的话那就直接引用,不需要创建。没有的话创建完毕之后在放入到字符串常量池中。

什么是String常量池

  • 要理解什么是String常量池需要了解所谓的堆,栈,方法区。这里我就不做过多解释,如果有不懂的小伙伴自己区查找资料去看看。这里我就简单说说:

  • 堆:一般放对象,那么也是GC常常光顾的地方

  • 栈:一般放引用

  • 方法区:一般放公共的资源,比如说被Static修饰的静态成员,包括final修饰的成员;

  • 那么知道了他们的作用,我们在来通过下面的代码和内存分配图来理解理解字符串的常量池:

示例:String a="abc";

String b="abc";

String c=new String("abc");

根据上面的代码答主自己画的内存图:

  • 通过上面的这个图我们来看看什么是常量池:

当我们创建了字符串变量a值为“abc”,当我们再次创建字符串变量b值和a一样,那么这个时候字符串b会到常量池中区找有没有“abc”这个值,有就直接引用;当我们在通过new方式再次创建一个对象c,它其实是在堆内存中创建了一个字符串对象,然后最后的值还是指向了字符串常量池中的已经存在的“abc”;

String常量池的作用是什么

通过上面的说明相信大家应该知道了String常量池的作用了,就是为了增加程序性能,减少频繁创建String对象带来的不必要的内存消耗和线程资源。

String面试题会被问到吗?

一般情况现在的是很少问答关于String的面试题了。如果真的问到了的话其实多半面试官想了解了解你对Java的jvm理解了。可能在几年前这种类似的问题还会问的稍微多那么一点点。所以题主还是多花点时间去了解jvm可能会更加好一点。

Java虚拟机内存结构图

总结:String常量池的存在就是为了增加程序效率的,那么它的内存图也不难理解,并且现在的面试中一般也很少去问到这类问题,所以可以花点时间去多学习Java的jvm会比较好点。

以上是答主自己的理解,如果觉得帮到各位了,麻烦给个赞,或者有更好理解的小伙伴可以在下方评论区留言,点个关注我们一起探讨探讨。


自学JAVA


为了便于理解,举个例子,有如下代码段:

String t0 = "helloworld";

String t1 = new String("helloworld");

上面代码在运行时会在Java虚拟机栈中创建一个String类型变量t0,然后会优先在方法区的运行时常量池中查找是否已经存在相同的字符串,倘若已经存在,栈中t0变量直接指向该字符串;倘若不存在,则在常量池中创建一个"helloworld"字符串,再将栈中t0变量指向该字符串。通过new关键字创建字符串对象,首先当前类被加载后,会在方法区的运行时常量池中查找是否已经存在"helloworld"字符串,如果不存在,则将编译期生成的"helloworld"存到运行时常量池中,如果已存在不存放,在堆中生成一个String类型的对象,栈中t1变量指向该对象。需要注意的是从JDK1.7开始,HotSpot虚拟机将字符串常量移至Java Heap。

这里再说一下String的intern方法,JDK1.7之前的版本中,intern方法会优先在方法区的运行时常量池中查找是否已经存在相同的字符串,倘若已经存在,则返回已存在的字符串,否则则在常量池中添加一个字符串常量,并返回字符串。因为从JDK1.7开始,HotSpot虚拟机将字符串常量移至Java Heap,intern方法的实现也发生了变化,首先还是会先去查询常量池中是否已经存在,如果存在,则返回常量池中的字符串,否则不再将字符串拷贝到常量池,而只是在常量池中保存字符串对象的引用。


分享到:


相關文章: