final关键词和可变,不可变数据类型的总结

序言

在java学习过程中产生了final 以及可变,不可变数据类型的疑惑,下面笔者对final 修饰词的作用以及场景,和可变数据类型,不可变数据类型进行总结。

1.可变性:

可变性可以分为两种,引用可变性以及对象可变性。引用可变性指的是在改变一个对象的值得时候可以新引用一个地址来储存新的值, 用final修饰的对象 引用无法改变。
对象可变指的是 一个对象可以在不更改引用内存的情况下直接更改值,比如StringBuilder。下文中会进行详细介绍。

不可变数据类型

当该数据类型的对应变量的值发生了改变**,那么它对应的内存地址也会发生改变**,对于这种数据类型,就称不可变数据类型。其中基本数据类型都是不可变数据类型。(可以理解为不可变数据类型拥有引用可变性但是没有对象可变性)
举例说明: int是一个不可变数据类型, int x = 1; 如果想要改变int对象的数据的话,那么它就需要指向一个内存中新的地址。

可变数据类型

当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型,当可变数据类型改变时它实际上是更改了内存中的内容(可以理解为可变数据类型同时拥有引用可变性和对象可变性,但是在更改可变数据类型的内容时,使用对象可变性,即直接更改内存中的内容而不改变地址。)

不可变数据类型和可变数据类型的快照举例

1.不可变数据类型

String x = "a";
x = x + b;

如下图所示,不可变数据类型不是说赋值之后内容不可变,而是指无法在引用同一地址的情况下改变对象的值。
在x = x + b的过程中 String 引用了新的对象。
在这里插入图片描述
2.可变数据类型

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

代码对应下图:
如图所示,StringBuilder是一个 可变数据类型,在更改内容的时候没有改变指向。
在这里插入图片描述
在实际编程时,如果使用for循环去相加String ,使用spotbug会报错,因为String 在循环相加时不断产生新的指针,这样很浪费空间,造成性能损失,所以系统会提示使用StringBuilder代替的直接相加。

final关键词的修饰

final用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖和类不可被继承
1.final 用来修饰数据类型的时候,表示这个数据类型 引用不可变,用final 修饰得数据类型在更改赋值的时候无法将引用的地址指向新对象。
如下代码所示:


 StringBuffer s = new StringBuffer("a");// StringBuffer是一个可变数据类型,对象可变且引用可变
s = new StringBuffer("ab");  //s被成功改为 ab
=====================
final StringBuffer s = new StringBuffer("a");// StringBuffer是一个可变数据类型,对象可变且引用可变
s = new StringBuffer("ab");  // 编译失败,因为s已经被final修饰,无法引用新的地址。
s.append("c") //更改成功,因为虽然final修饰的数据类型无法引用新对象但是没有影响对象可变性,即对象的内容可以直接更改。

2.final修饰方法的时候,表示,该方法不允许任何子类重写这个方法,但子类可以使用这个方法。
3.final类:当一个类被声明为final时,此类不能被继承,所有方法都不能被重写,但是final类的成员变量未受影响,即类成员并非不可改变,除非将成员变量也增加final修饰符。因此,final修饰的类不一定是可变的,取决于这个类是否有可变的方法。

不可变类

不可变类是指当创建了这个类的实例后,就不允许修改它的值了,也就是说一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了,只允许被读,但不允许被修改。
如何构造一个不可变类?

类中所有成员变量被private修饰。
类中没有写或者修改成员变量的方法。
确保类中所有方法不会被子类覆盖,可以通过把类定义为final或者将类中方法定义为final。
如果一个类成员不是不可变量,那么在成员初始化或者使用get方法获取该成员变量时,需要通过clone方法来确保类的不可变性。

不可变类具有使用简单、线程安全、效率高(直接复制地址因为内容不变)等优点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值