String底层原理

今天模拟面试遇到一位同学,刚好问到一个问题

我问他 String的底层原理是什么

他思考了一会说不知道。

那么我们在面试的时候有可能会遇到类似的问题,怎么去解答,肯定是要去看String的源码的

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    

    private final char value[];

     private int hash; // Default to 0

    
    private static final long serialVersionUID = -6849794470754667710L;
    
    ......此处省略N多代码
    
    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

}

在上面 贴出了String的源代码,我们可以看到,String类是final修饰的,然后还有个成员属性 value  它也是final的并且是一个char类型的数组

通过构造方法可以看到,我们传递的参数值 是直接赋值给了 value 

那么我们说明 String它是一个不可变字符串,底层是一个char类型的数组

实际上我们经常 这样写 String  a = "abc"; 这个时候 声明的变量值是在常量池中的。

到此,有的同学可能要说了,String里面我们不是可以使用 + 连接符 来进行String的拼接吗。

的确如此,我们是可以使用 "+" 来拼接字符串,不过 这里 jdk的虚拟机是做了优化的,并不是表面看到的使用 连接符 对原来的String做了拼接,那么我们来看下 它是如何编译的。

有如下代码:

public class Test{
	public static void main(String [] args){
			String str = "abc";
			String str1= "def";
			str = str+str1;
			System.out.println(str);
	}
}

我们在控制台 中 通过 javac 编译,然后通过java执行 看到结果是

结果都知道是 "abcdef" 那么这个地方的str到底是否被改变,我们可以看编译后的class字节码文件

我们通过 javap -c Test 来观察,结果如下图

我们看到Code 的 第 0 和 第 3 标识处,是我们声明的变量值  "abc" 和 "def"

再往下走,我们在java中的代码是使用了 "+" 连接符号的,此处看到 Code 第  6 处 new StringBuilder  

再往下走,看到 Code 的第 14 和 第 18 ,使用了StringBuilder的 append(),那么我们可以得出一个结论,我们在使用String的时候,使用连接符,并不是表面看到的是直接操作原来的变量做值的拼接,而是使用的StringBuilder对象,追加的内容,

最后 在 Code的21处,有一个 toString()方法,是把当前StringBuilder的对象变成了String。

好了,到此,我们剖析String源码到此结束。

结论就是 String底层是一个不可变字符串,使用连接符的时候,实际上是经过了StringBuilder的优化处理的。并不是在原来的String对象中做追加

 

String底层原理是指String类在内存中的实现方式。根据引用的观点,String类是final修饰的,底层使用char[]数组来存储字符串内容,并且该char[]数组是被final修饰的,即不可变。这意味着一旦字符串被创建,它的内容就不能修改。 当我们使用字面量声明String时,如引用中的示例代码所示,编译器会将字符串直接存储在常量池中,而不是在堆内存中创建新的对象。这样做的好处是可以节省内存空间,并且多个字符串常量可以共享同一份内存。 需要注意的是,由于String是不可变的,如果我们对一个字符串进行修改操作,实际上是创建了一个新的String对象。这也是String不适合频繁修改字符串的原因之一,因为每次修改都会创建新的对象,导致内存开销较大。 总结来说,String底层原理是通过char[]数组来存储字符串内容,并且字符串常量会被存储在常量池中以提高内存利用率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [面试系列之String原理详细讲解](https://blog.csdn.net/lgy_2021/article/details/124787916)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值