Java中字符串常见题之弦相关讲解

  

今天给大家带来的是在面试中经常被问到的一道题:

  

无论在Java还是Android中,字符串是一个很常见的类,但是大家真的很了解吗,我这里有几个题:

  

1。         字符串str1=癮bc”;   字符串str2=新的字符串(“abc”);      

这两种创建字符串对象的方法有什么不同?

  

2。         字符串s=癮”+“b”+“c”+“d”;      

这里面一共创建了多少对象?

  

这两道题昨天给笔者搞得是一脸懵逼,后来一听这是一道很经典的面试题,就赶快查阅各种资料,现在已经解决了。

  

在解决这两个题之前,我们先来明确几个知识点,相信把这几个知识点弄完之后再回头看这两个题,就很简单了:

  
      <李> 1。引用在栈内存中存储,对象在堆内存中存储。   <李> 2.字符串对象不可变。   <李> 3.字符串创建对象的形式:李   <李> 4。字符串常量池的意义:李   <李> 5.实习生()方法使用。   
  

我们首先来开第一个:

  

<强>引用在栈内存中存储,对象在堆内存中存储。

  

癑ava中字符串常见题之弦相关讲解"

  

这个是我粗略画的一张图,这张图可能不是很准确,但是我只想表达一个意思,我们的栈内存,存放的是我们对象的引用和我们基本数据类型的值。而堆内存中存放的是我们的对。就象是这么简单。

  

<强>为什么说字符串对象不可变

  

这里我们用一下大佬的图:

  

癑ava中字符串常见题之弦相关讲解"

  

如果用代码表示上面的图,那就是:

        字符串s=癮bcd”;   s=s +“el”;      

如果没有上面这张图,大家可能会觉得我们只是给年代对象后面加了一个el,这不还是原来的吗?不,我们说的字符串对象不可变就是这个意思,当我们给年代再加上el时候,新的字符串abcdel被存放到了一个新的内存中。已经不是原来的内存了,所以说字符串对象不可变,如果变了,那就已经变成了一个新的对象。

  

那说到这里大家可能会返回去看我写的第二个问题:按你的说法这不就7个对象吗? abcd各占一个,每次+到一起都要重新生成对象,一共生成了7个对象。话是没错,但是我想说这道题说多解,等我们讲完了下面这两个知识点,这道题就完全解开了。

  

<强>字符串创建对象的形式:

  

正如我们上面看到的,字符串有两种创建对象的形式:

  

1。字面量形式:

        字符串str="自闭症";      

2。标准的新形式:

        字符串str=新的字符串(asd);      

<强>字符串常量池的意义:

  

字符串常量池,又称为字符串在字面量池。大家不要他想象的多么高深额,其实说白了他就是一块内存,它里面存放的是我们的字符串的引用。

  

大家可能疑问这个东西有什么意义:假如我们要创建一个字符串,“一个”+“b”+“c”+ ....+我们+了一万次,那么按照上面的说法,我们是不是为了创建一个很长的字符串,创建了很多的对象。这样不但有的字符串被重复的创建了,而且占用了很多不必要的内存,代价有点大。

  

我们的JVM为了减少字符串的重复创建,维护了一个特殊的内存:就是这个字符串常量池。

  

在这个字符串常量池中,存放着我们字符串对象的引用。下面我们根据字符串创建对象的两种形式来说明一下常量池是如何存放弦对象引用的:

  

1。通过字面量创建字符串对象:

  

癑ava中字符串常见题之弦相关讲解"

  

我们举个例子,字符串str=癮bc”;我们通过字面量形式创建一个值为“abc”的对象,首先我们判断常量池中是否存在一个引用,这个引用的值也是“abc”,如果有这个值,那么我们就从常量池中拿到这个引用,返回给str。

  

如果没有,那么我们就创建这个对象,然后把str这个引用值放到常量池中。

  

在这里我们要明确几个点了: