从String和StringBuilder浅析java中的“可变”与“不可变” 您所在的位置:网站首页 人教版九年级上化学教材 从String和StringBuilder浅析java中的“可变”与“不可变”

从String和StringBuilder浅析java中的“可变”与“不可变”

2024-06-05 20:16| 来源: 网络整理| 查看: 265

前言:可能快要线上考试了,本人刚刚开始复习0.0,理清了一些之前觉得有些混乱的概念,特在此分享一下自己的理解,希望也能帮到其他人

1.数据类型中的可变与不可变

我们知道,java中有可变数据类型和不可变数据类型之分,那么我们首先要理清,这里的变与不变指的是什么在变化或是保持不变? 在前面的博客中也有所总结,变化可以有两种:值的改变与引用的改变 很显然,这里的变化或是不变指的就是值的变化或是不变。 很简单的道理,我们可以拿String来分析,我们知道,String是不可变的数据类型,但你肯定写过类似的代码:

String s="Hey"; s=s.concat(" Guys!");

这样的代码很显然是正确的,它没有违背String的不可变的特性,因为生成了一个新的字符串"Hey Guys!" ,而原来"Hey"字符串的值没有变,而仅仅是s字符串的引用发生改变:从指向"Hey"变为指向一个新的字符串"Hey Guys!"。因此数据类型中的变化是指“值的变化”。

2.final关键字

java中还提供了final关键字来提供额外的不可变,而这种不可变是针对引用的。笔者曾经并未考虑这些,直到今天复习才终于理清。 即被final修饰的变量,一经指定,就总是保持同一个引用,指向相同的地址空间,无论这个空间上的值是否发生改变。 如果将1中例子的s用final进行修饰,结果会是什么样呢?

final String s="Hey"; s=s.concat(" Guys!");

结果在编译时就会直接报错: 在这里插入图片描述 因为我们为s指定了新的引用,而这与final的约束相违背

3.可变数据类型的不可变引用

理清了1和2,我们接下来看看将final应用到可变数据类型会怎么样,先来理论上分析一下,这是完全行得通的,因为本身数据类型是值可变的,比如下面这段代码:

StringBuilder sb=new StringBuilder("a"); sb.append("b");

这与1中String类型的例子非常相似,对于不可变数据类型String来说,其要保证每个字符串时不可变的,因此在末尾连接字符串的操作就会产生一个新的字符串。而对于可变数据类型StringBuilder来说,其值是可变的,因此可以在值"a"上直接连接"b",其变化的过程如图所示: 在这里插入图片描述 值的变化直接在同一个地址空间上就可以完成。但这时你还可以为他重新指定引用,让它指向新的地址。 那么理论上就可以为其加上final,实现引用不可变,即sb永远都只能指向图中所示的这一个地址,但在地址内部值是如何变化的,这就无法进行约束了。 像下面这段代码:

final StringBuilder sb = new StringBuilder("abc"); //改变值 sb.append("d"); //改变引用 sb = new StringBuilder("e");

前面的append是在保持引用的情况下改变其值,这是允许的,但用final修饰以后,后面sb = new StringBuilder(“e”);再想修改引用就会报错了: 为了验证,我们在两个变化后面都加上一条println语句:System.out.println(sb);进行打印,查看结果: 在这里插入图片描述 这里引用的改变提示错误

在这里插入图片描述 可以看到这里改变值的操作是成功的!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有