java 可变 不可变_java中的不可变类型的探究
不可变类是指创建类的对象实例后,该实例的属性不能发生改变。常见的String就是不可变类。不可变类型的属性值不会发生改变,这在多线程编程的时候非常有用,不用担心对象的属性值被修改。
下面我们来看看如何实现一个不可变类型:
1.要保证属性值不发生改变,属性必须用private和final修饰。
2.要在类的构造函数中初始化final属性,并且只提供getter方法,不提供setter方法。
3.重写equals和hashCode,使用重写的equals方法根据属性值判断两个对象是否相等,hashCode方法保证不同的对象,hashCode不同。
最简单的不可变类实现方法:
classPerson
{privatefinal String firstName;privatefinal String lastName;publicPerson(String firstName,String lastName)
{this.firstName=firstName;this.lastName=lastName;
}publicString getFirstName()
{returnfirstName;
}publicString getLastName()
{returnlastName;
}
@Overridepublicboolean equals(Object obj)
{if(obj instanceof Person)
{
Person p=(Person)obj;return this.firstName.equals(p.firstName)&&this.lastName.equals(p.lastName);
}else{throw newClassCastException();
}
}
@Overridepublic inthashCode()
{return (this.firstName+this.lastName).hashCode();
}
}
Person类就是一个不可变类,属性都是private和final类型,并且只提供了getter方法,根本无法修改属性的值。
但是如果一个类中包含了一个可变类型那就不能这么简单的实现了。
className
{privateString firstName;privateString lastName;publicName() {}publicName(String firstName, String lastName)
{this.setFirstName(firstName);this.setLastName(lastName);
}publicString getFirstName() {returnfirstName;
}public voidsetFirstName(String firstName) {this.firstName =firstName;
}publicString getLastName()
{returnlastName;
}public voidsetLastName(String lastName)
{this.lastName =lastName;
}
}classPerson
{privatefinal Name name;publicPerson(Name name)
{this.name=name;
}publicName getName()
{returnname;
}
@OverridepublicString toString()
{return name.getFirstName()+"$"+name.getLastName();
}
}
Person类中含有一个可变类型Name,虽然Name被final和private修饰,并且只有getter,但是仍然可以修改Name的值:
Person person=new Person(new Name("Hello","world"));
System.out.println(person);
person.getName().setFirstName("hel");
System.out.println(person);
输出结果:
Hello$world
hel$world
很明显不能达到不可变类的目的,要想变成不可变类,需要在getter中返回一个新的对象,在构造器中也要用新的对象初始化:
publicPerson(Name name)
{this.name=newName(name.getFirstName(),name.getLastName());
}publicName getName()
{return newName(name.getFirstName(),name.getLastName());
}
这样就完全不会改变对象实例的值了。String类就是使用了类似的实现方法,不过使用的常量缓存池,大大提高了性能。每次初始化String对象是都会先检查常量缓存池,如果已经存在则不会再内存中创建新的常量字符串了。
java 可变 不可变_java中的不可变类型的探究相关推荐
- java string字节大小_Java中char[] 和 String 类型占用字节大小问题
作者:威威喵 原文链接:https://blog.csdn.net/smile_Running/article/details/87211916 在 C 语言中 1.char a[10] = {&qu ...
- java比较时间戳大小_JAVA中两个String类型的时间戳怎么样比较大小?
1.从数据库里面获得的时间戳是String类型的,要与当前时间比较,判断登陆是否过期 生成一long类型的当前时间,把String类型强制转换成long类型报错,代码如下: long currentT ...
- java函数式编程入口_Java中的函数式编程
前言 JDK8引入的Lambda表达式和Stream为Java平台提供了函数式编程的支持,极大地提高了开发效率.本文结合网络资源和自身使用经验,介绍下Java中的函数式编程 Java中的函数式编程 出 ...
- java可以多重继承吗_Java中的多重继承与组合vs继承
java可以多重继承吗 有时我写了几篇有关Java继承,接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...
- java中有没有栈_Java中堆和栈有什么区别
stack 和 heep 都是内存的一部分stack 空间小,速度比较快, 用来放对象的引用heep 大,一般所有创建的对象都放在这里.栈(stack):是一个先进后出的数据结构,通常用于保存方法(函 ...
- java包装器类_Java中的基本类型和包装类
Java中基本数据类型与包装类型有 基本类型 包装器类型 boolean Boolean char Character int Integer byte Byte short Short long L ...
- java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...
- java 验证码透明背景_Java中的证书透明度验证
java 验证码透明背景 因此,我有一个幼稚的想法,即除了证书有效性检查(在Java中)之外,将证书透明性验证作为每个请求的一部分也很容易. 牺牲了整个周末的一半时间,我可以证明这并不是一件小事. 但 ...
- java构造器详解_Java中关于构造器的使用详解
这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下 Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行 ...
最新文章
- java值参_Java陷阱之慎用入参做返回值详解
- crt脚本怎么添加等待时间_secureCRT自动化脚本(之定时任务)
- 广州电子厂房净化工程_简述设计电子车间净化工程的注意要点
- yeomanbower
- python独立环境——virtualenv
- c#中高效的excel导入oracle的方法
- SLAM_信息矩阵协方差矩阵
- 解决电脑右键新建没有文本文档的问题
- SoapUI被动接口的压力测试/性能测试
- 西工大第三届“探索·解密”趣味密码比赛-个人WriteUp
- 之前安装过Multisim14,再次安装失败的解决方法
- 【Hill Cipher】希尔密码描述 by Xiaosi_lemon
- 启动Activity时显示空白界面的问题
- mysql获取字符串长度函数(CHAR_LENGTH)
- outlook客户端 outlook.com邮箱设置方法
- MySQL8下载安装卸载教程
- Variational Inference入门:variational bayesian EM
- 面对来势汹汹的AI大潮,你该如何应对?
- 2021github仓库操作流程手册指南
- 电子科技大学858通信考研最新情况分析