Java基础知识:String为什么是不可变类型?

String

String是不可变类型。这里的不可变是指,当编译器开辟堆内存来存储String内容后,这个堆内存无法再被外界修改。

但是,程序员可以创建一个String类型变量,通过赋值的方式,使之指向不同的堆内存,从而产生String字符串可变的假象。

由于String字符串的不可变性,就导致拼接、提取字符串的过程中,需要创建新的堆内存来存放结果,这和直接修改堆内存相比要低效的多。

但是Java语言的设计者为什么要这么做呢?

  1. 不可变字符串有一个优点:编译器可以让字符串共享。也就是说相同内容的字符串,其实是共享同一个堆内存的,不管你创建多少个,只要字符串内容一样,其幕后都指向一个堆内存。
// 不信,你试试
String s1 = "Hello World!";
String s2 = "Hello World!";
//注意:判断两个字符串是否指向同一个内存地址,需要使用‘==’,使用equal是判断两个字符串内容是否相等,注意这两个概念的区别!
System.out.println(s2 == s1);
//你会发现打印结果是:true

字符串共享机制,会使得字符串比较变得非常简单,因为指向同一个堆内存地址的字符串肯定是相等的,而不需要挨个遍历字符。(P.S. 当然了,如果两个字符串并非指向同一个地址,则还是需要比对字符串内容)

注意!!!判断两个字符串是否相等,一定要使用 s1.equals.(s2),而不能直接使用s1 == s2,否则你会遇到很奇怪的调试现象,别怪我没提醒你 -_-||

  1. 字符串其实很少被修改。翻翻代码你就会发现这个结论。不过,话说回来,如果我真想就像频繁改动字符串,该怎么办呢?Java推荐你使用StringBuilder

这就是为什么,简单拼接字符串时,你可以优雅地使用字符串拼接符+;当频繁构建字符串时,拼接符+的低效性就暴露出来,StringBuilder虽然难看,但很高效。优雅和高效,二者难以兼得。

final

final关键字是用来控制变量初始化后的对象引用不会再指向其他对象。
String本身是一个不可变的类,指的是不可修改String对象的内容。

如果要确保String类型变量定义之后,永不可变(不可再指向其他堆内存),可以使用final修饰之。

//我们既没办法修改s指向的堆内存的内容,也无法将新的String对象赋值给s.
//因此s永不可变。
private final String s = "Hello World!";

final也可以用来修饰可变类,例如StringBuilder:

private final StringBuilder sb;
sb = new StringBuilder();

//虽然使用final修饰StringBuilder,由于StringBuilder属于可变类,
//因此我们依然可以通过append方法修改sb对象所指向的堆内存的内容。
//但是我们无法重新让sb指向一个新的StringBuilder对象引用。
sb.append("abcd");//正常
sb.append("1234");//正常
sb = new StringBuilder();//无法执行
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值