Java中的不可变类

什么是 Java 中的不可变类? 不可变类是指在创建后其状态(对象的字段)无法被修改的类。一旦对象被创建,它的所有属性都不能被更改。这种类的实例在整个生命周期内保持不变。关键特征声明类为final,防止子类继承。类的所有字段都是private和final,确保它们在初始化后不能被更改。通过构造函数初始化所有字段。不提供任何修改对象状态的方法(如setter方法)。如果类包含可变对象的引用,确保这些引用在对象外部无法被修改。例如 getter 方法中返回对象的副本(new 一个新的对象)来保护可变对象。String。 阅读详情

在学习Java的过程中,我们时常会遇到这样一个概念——不可变类。本文旨在对此做一简单的解释。
不可变类 不可变类 不可变类 不可变类 不可变类 不可变类 不可变类

1. 不可变类:创建该类的实例后,该实例的属性是不可改变的,java提供的包装类和java.lang.String类都是不可变类。当创建它们的实例后,其实例的属性是不可改变的。

          例如:Double d = new Double(2.3);

                    String str = new String("hello");

为上面两个类传入了2.3和"hello"作为参数,那么Double类和String类肯定要提供实例属性来保存这两个参数,但程序无法修改这两个实例属性,因为Double类和String类没有提供修改这两个属性的方法。

2.自定义不可变类的规则:

        1).使用private 和final修饰符修饰变量。

        2).提供带参数的构造器用于根据参数来初始化类里的属性。

        3).仅为该类的属性提供getter方法,不提供setter方法。

        4).如果有必要,重写Object类中的equals方法和hashCode方法:在equals方法中根据关键属性来作为两个对象相等的标准,还要保证两个equals方法判断相等的对象的hashCode 也相等。例如:系统提供的String类:equals:根据对象里的字符序列来作为相等的标准,hashCode方法也是根据字符序列计算得到的。

3.如果要设计一个不可变类,必须注意其引用类型的属性:

        如果引用变量属性的类型是可变的,必须采用必要的措施保护所引用的对象不会被改变,这样才能创建真正的不可变类。

        定义一个不可变类Person (person 中有一个引用类型为Name的name属性变量,Name类型是可变类),为了保持person对象的不可变,必须保护好person对象的引用类型属性:name。让程序无法访问到person对象的name属性,也就无法利用name属性的可变性来改变person对象了。

package com.xjtu.cruise;

public class Name {
	private String firstName;
	private String lastName;

	public Name() {
	}

	public Name(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getLastName() {
		return this.lastName;
	}
}
package com.xjtu.cruise;

public class Person {
	private final Name name;

	public Person(Name name) {
		this.name = name;
	}

	public Name getName() {
		return name;
	}

	public static void main(String[] args) {

		Name n = new Name("Jordan", "Mike");
		Person p = new Person(n);
		System.out.println(p.getName().getFirstName());
		// 改变Person对象的name属性的firstName属性值。
		n.setFirstName("Jackson");
		// Person对象的Name属性firstName属性值为"Jackson"
		System.out.println(p.getName().getFirstName());
	}
}
输出结果可见name对象的属性firstName已经改变,可见这里的person不变类已经失去了意义。

思考:

不可变类中的属性为引用类型,该引用类型若是可变类,为了确保我们定义的不可变类确实是不可变类,让程序无法访问到person对象的name属性。

       1.为什么能改变person对象的name属性?name属性为引用类型,在person类构造器中为name属性初始化(参数传递:引用传递),n与name属性有相同的内存地址,改变n指向的对象值,name和n指向的其实是同一个对象,所以也就改变了(不让name与n有相同的内存地址,且隐藏name属性的内存地址,不让程序访问到该引用)。

       2.解决:不让引用地址相同(name与n不指向同一个地址),既不是同一个对象,但要求对象的内容相同。于是有:
         改写person类:

package com.xjtu.cruise;

public class Person {
	private final Name name;

	public Person(Name name) {
		// this.name = name;
		this.name = new Name(name.getFirstName(), name.getLastName());
	}

	public Name getName() {
		// return name;
		return new Name(name.getFirstName(), name.getLastName());
	}

	public static void main(String[] args) {

		Name n = new Name("Jordan", "Mike");
		Person p = new Person(n);
		System.out.println(p.getName().getFirstName());
		// 改变Person对象的name属性的firstName属性值。
		n.setFirstName("Jackson");
		System.out.println(p.getName().getFirstName());//Jordan
	}
}

Person类改写了设置name属性的方法,也改写了返回name属性的方法。

当程序向Person对象传入一个Name对象时,该构造器创建Person对象时并不是直接利用已有的Name对象,而是重新创建了一个Name对象来赋给Person对象的name属性,当Person对象返回name属性时,并没有直接把name属性返回,直接返回name属性也可能导致该name属性所引用的Name对象被修改,而是直接返回新创建的Name对象。


              

2 、什么是Java中的不可变类 不可变类是指其对象一旦创建后,其状态(字段值)就不能再改变的类。设计不可变类时需要确保字段值在对象创建时就被初始化,且没有“setter”方法来修改字段值。优点:线程安全、提高代码的可维护性和安全性,适合用于多线程编程和缓存。缺点:性能开销较大,灵活性较差,尤其在需要频繁修改对象状态的场景下。不可变类的设计理念和实践是Java编程中非常重要的技术,尤其在并发编程和设计高质量、可靠的应用时,具有重要的作用。 阅读详情

相关推荐

开源onlyoffice编译完整过坑版

onlyoffice 编译过坑完整版;

sHImart 4551

java常见不可变类_Java语言不可变类的诀窍

示例不可变对象是状态无法更改的对象。不可变类是其实例根据设计和实现是不可变的类。作为不可变性示例最常见的Java类是java.lang.String。以下是陈规定型的示例:publicfinalclassPerson{privatefinalStringname;privatefinalStringssn;// (SSN ==社会安全号码)publicPerson(...

weixin_30802819的博客 265

VTK学习(入门级教程,包括安装和使用)~持续更新中

说明:研究QT+VTK有段时间了,准备把学到的东西分享给大家,这篇博客以VS+QT+VTK为主进行展开学习的。

HXX904的博客 4756

Java可变类型与不可变类型

HIT软件构造-关于Java可变类型与不可变类型的一点理解

weixin_51611639的博客 3463

AirSim安装和地图加载

详细教程如何安装AirSim并加载地图

fegxg的博客 3033

从零到一:手把手教你用DJI E-Port套件为M350 RTK开发第三方负载(PSDK V3实战)

本文详细介绍了如何使用DJI E-Port套件为M350 RTK开发第三方负载,涵盖硬件配置、开发环境搭建及实战应用。通过PSDK V3开发套件,开发者可以高效实现负载与无人机的通信,适用于电力巡检等工业场景,提升开发效率与系统稳定性。

weixin_26841743的博客 701

Java的可变类与不可变类

什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类型?不可变对象,顾名思义就是创建后不可以改变的对象,典型的例子就是Java中的String类。

zzdnb的博客 805

最新2026年《网络数据安全风险评估办法》条款解读

大型企业集团IT变革下的零信任安全体系建设方案(55页).pptx。以数据安全为核心的安全立体防御体系解决方案(41页).pptx。让数据安全合规地创造价值(15页 PPT).pptx。大型集团数据安全应急预案(57页).docx。数据安全治理与评估服务业务介绍.pptx。数据安全管理实践(17页).pptx。大数据安全架构设计方案.pptx。大数据安全规划总体方案.pptx。数据库安全综合治理方案.pptx。医疗数据安全建设方案.pptx。数据安全框架规划图.pptx。数据安全治理方案.pptx。

cdfunlove的博客 47

JAVA中的不可变类

定义:一旦对象被创建,在整个生命周期里面,所有的属性都不可被改变。

决战软件之巅的博客 589

Android 13.0 展讯平台关机充电动画横屏显示修改

在13.0的系统rom定制化开发中,在关于展讯平台的产品中,系统默认的充电动画是竖屏显示的,但是在像平板的产品中竖屏动画肯定不符合规范, 所以需要在平板TV产品中,充电动画同时也是需要修改为横屏显示的,接下来就来分析下充电动画的相关绘制流程,然后实现功能

安卓兼职framework和app工程师的博客 409

【STM32项目】基于Stm32c8t6-镭射激光打印机的设计(完整工程资料源码)

随着打印技术的快速发展,镭射打印技术也开始得到越来越广泛的应用。这种技术可以被用于在木材、塑料、皮革、织物等各种材料上进行图形打印,并且通常比传统机器更快、更准确和更灵活。

嵌入式技术开发 7198

Java不可变类机制

不可变类(Immutable Class):所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。

Hopefully Sky的博客 5102

ICC2:平行打孔create_pg_stapling_vias

power rail(follow pin)不总是metal1一成不变的,当需要使用metal2做power rail,而standard cell的pg pin仍然是metal1时就需要平行打孔,从metal2到metal1。 以往都是用create_pg_vias -allow_parallel_objects来做,但这样有两个弊端,一是需要抓出所有的via12(包括standard cell内部的和出pin绕线产生的),添加routing blockage,防止create pg via的时候产生d

m0_61544122的博客 2258

Java的不可变类

不可变类(immutable class)是指当创建了这个类的实例后,就不允许修改它的值了。也就是说,一个对象一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了。它有点类似于常量(const),即只允许别的程序读,不允许别的程序进行修改。 在Java类库中,所有基本类型的包装类都是不可变类,例如Integer、Float等。此外,String也是不可变类。可能有人会有疑问,既然Strin

学在途中 2428

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java 不可变类有什么用_Java中的不可变类理解

一、Java中的不可变类不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量。可变类(Mutable Objects):类的实例创建后,可以修改其内容。Java 中八个基本类型的包装类和 String 类都属于不可变类,而其他的大多数类都属于可变类。二、与引用不可变的区别需要特别注意的是,不可变类的不可变是指该类的实例不可变而非指向该实例的引用...

weixin_32382353的博客 311

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

《Java中的不可变类》

1 //不可变类举例: 2 /* 3 下面程序试图定义一个不可变类Person类,但=因为Person类包含一个引用类型的成员变量, 4 且这个引用类是可变类,所以导致Person类也变成了可变类。 5 */ 6 class Name1 7 { 8 private String firstName; 9 private Strin...

133

java中的不可变类

String是java中的不可变类,不可变类有它存在的意义。首先看一个例子。 public static void main(String[] args) { BigInteger one = new BigInteger("1"); BigInteger two = new BigInteger("2"); BigInteger three =

535

JAVA 不可变类

本文与个人博客 zhiheng.me 同步发布,标题: Java中的不可变类。 Java中的不可变类 不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量。 可变类(Mutable Objects):类的实例创建后,可以修改其内容。 Java 中八个基本类型的包装类和 String 类都属于不可变类,而其他的大多数类都属于可变类。 与引用不可变...

weixin_42306440的博客 303

Java面试必备:Java中的不可变类详解

不可变类(Immutable Class)是指一旦创建后,其状态(即成员变量的值)不能被修改的类。Java中的许多核心类都是不可变的,例如String、Integer、Long等。

qq_58299462的博客 837

java 不可变类_如何在Java中创建不可变类?

如果对象的状态在构造后无法更改,则该对象是不可变的。不可变的对象不会让其他对象修改其状态。对象的字段在构造函数内部仅初始化一次,以后再也不会更改。在本文中,我们将定义在Java中创建不可变类的典型步骤,并阐明开发人员在创建不可变类时遇到的常见错误。1.不可变类的用法如今,每个软件应用程序的“必备”规范都将被分发和使用多线程。多线程应用程序总是使开发人员感到头疼,因为要求开发人员保护其对象的状态,以...

weixin_30134531的博客 215

java 不可变类有什么用_Java不可变类机制浅析

不可变类(Immutable Class):所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。可变类(Mutable Class):相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。不可变类的特性对JAVA来说带来怎样的好处?1)线程安全:不可变对象是线程安全的,在...

weixin_35706281的博客 218

Java不可变类的设计

1.1 不可变类 不可变类是指其实例创建后状态不能被修改的类。它们的实例信息是由调用构造函数时就提供,不会提供对外的设值方法,保证它们的状态不会被改变。 1.1.1不可变类的好处 在Java平台类库中包含许多不可变的类,如String、基本类型的包装类以及Collections工具类中Unmodifiable对应各种集合的实现。不可变类比可变类更加易于设计、实现和使用...

leftyul的博客 869

java不可变类的意义_Java中的不可变类理解

一、Java中的不可变类不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量。可变类(Mutable Objects):类的实例创建后,可以修改其内容。Java 中八个基本类型的包装类和 String 类都属于不可变类,而其他的大多数类都属于可变类。二、与引用不可变的区别需要特别注意的是,不可变类的不可变是指该类的实例不可变而非指向该实例的引用...

weixin_35713233的博客 188

Java中的不可变类详解

Java中的不可变类是指创建后状态无法修改的类,如String、Integer等。实现要点包括:声明类为final、字段设为private final、通过构造函数初始化、不提供setter方法、对可变字段返回防御性副本。不可变类具有线程安全、简化并发编程、缓存友好等优点,但每次修改需创建新对象可能带来性能开销。典型应用场景包括多线程环境、缓存键值、函数式编程等。

xiongwenhao6的博客 527
上一篇: Windows下python环境变量配置
下一篇: OSGI入门实例讲解(一)
hxwhou
博客等级 码龄16年 100粉丝 64原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值