创建正真的Java不可变类
如果需要设计一个不可变类,尤其要注意其引用类型Field,如果其引用类型Field的类是可变的,就必须采取必要的措施来保护该Field所引用的对象不会被修改,这样才能创建真正的不可变类。
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;
}
public String toString() {
//return getClass().getName() + "@" + Integer.toHexString(hashCode());
return getClass().getName() + "@[firstName=" + this.getFirstName() + ", lastName=" + this.getLastName() + "]";
}
}
class Person1 {
private final Name name;
public Person1(Name name) {
this.name = name;
}
public Name getName() {
return this.name;
}
public String toString() {
//return getClass().getName() + "@" + Integer.toHexString(hashCode());
return getClass().getName() + "@[name=" + this.getName() + "]";
}
}
class Person {
private final Name name;
public Person(Name name) {
// 设置name为临时创建的Name对象,该对象的firstName和lastName与
// 传入的name对象的firstName和lastName相同
this.name = new Name(name.getFirstName(), name.getLastName());
}
public Name getName() {
// 返回一个匿名对象,该对象的firstName和lastName与
// 该对象里的name的firstName和lastName相同
return new Name(name.getFirstName(), name.getLastName());
}
public String toString() {
//return getClass().getName() + "@" + Integer.toHexString(hashCode());
return getClass().getName() + "@[name=" + this.getName() + "]";
}
}
public class PersonNameImmutableTest {
public static void main(String[] args) {
Name n1 = new Name("悟空", "孙");
Person1 p1 = new Person1(n1);
// Person对象的name的firstName值为“悟空”
System.out.println(p1.getName().getFirstName());
// 改变Person对象的name的firstName值
n1.setFirstName("八戒");
// 下面的输出为“八戒”,已经改变了原来的值“悟空”
System.out.println(p1.getName().getFirstName());
// 上面的运行结果说明,Person对象的name的firstName值已经被改变了,
// 这就破坏了设计Person类的初衷
//为了保持Person1对象的不可变性,必须保护好Person1对象的引用类型Field:name,
//让程序无法访问到Person1对象的name Field,也就无法利用name Field的可变性来改变
//Person1对象了。
//为此,我们将Person1类该为Person类使用即可。
Name n = new Name("悟空", "孙");
Person p = new Person(n);
// Person对象的name的firstName值为“悟空”
System.out.println(p.getName().getFirstName());
// 改变Person对象的name的firstName值
n.setFirstName("八戒");
// 这样,无论如何修改name的值,Person对象的name值不会改变,
// 以下输出依然为“悟空”
System.out.println(p.getName().getFirstName());
}
}
或者做如下修改:
将Name类的setter方法删除掉,这样Name类是不可变的类,Person1类也是不可变的类。
创建正真的Java不可变类的更多相关文章
- Java 不可变类
Java 不可变类 immutable object 不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值. 如JDK内部自带的很多不可变类:Interger.Long和String等. * ...
- JAVA的可变类与不可变类
转自: http://www.blogjava.net/hilor/articles/150610.html 可变类和不可变类(Mutable and Immutable Objects)的初步定义: ...
- 【转】Java的可变类与不可变类
1.可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容. 不可变类:当你获得这个类的一个实例引 ...
- JAVA不可变类(immutable)机制与String的不可变性--非常好.
JAVA不可变类(immutable)机制与String的不可变性 https://www.cnblogs.com/jaylon/p/5721571.html
- 创建Java不可变类
不可变(immutable)类的意思是创建该类的实例后,该实例的Field是不可改变的,Java提供的8个包装类和java.lang.String类都是不可变类. 如果需要创建自定义的不可变类,可遵守 ...
- JAVA不可变类(immutable)机制与String的不可变性
一.不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值.如JDK内部自带的很多不可变类:Interger.Long和String等. 可变类:相对于不可变类, ...
- 【Java基础】JAVA不可变类(immutable)机制与String的不可变性
一.不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值.如JDK内部自带的很多不可变类:Interger.Long和String(8种基本数据类型的包装类和S ...
- JAVA不可变类与可变类、值传递与引用传递深入理解
一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...
- Java不可变类与final类
概念 Java的不可变类是指八个基础类型的包装类和String,他们的数据成员是不可变的.使用加法等操作时,其实是创建了一个新的对象. Java的final类是对类用关键字final进行修饰,说明该类 ...
随机推荐
- word 操作教程
http://blog.163.com/haolongqin@126/blog/static/10999842220159993540527/ https://blog.csdn.net/ibigpi ...
- Hadoop家族系列文章
转自:http://blog.fens.me/series-hadoop-family/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, H ...
- MFC 单选按钮Radio使用注意
使用MFC Radio时遇到问题:数据交换时出现断言崩溃框 定位于: 解决方法: 1.按CTRL+D,保证同一组内的radio的tab序号是连续的: 2.同一组内,设置 radio1的属性: gro ...
- sizeof 数组与指针
在学习指针的时候,得到指针的定义和数组的定义一样,但是这时候就很好奇,指针只是一个地址,那数组和指针一样的话,sizeof时怎么得知其长度呢. 于是百度了下面的回复: 千万不要把数组名看成指针,尽管有 ...
- 如何在VS2010中更好的编写JavaScript代码
VS2010默认的JavaScript代码编辑器相对简单.对于大家熟悉的代码折叠,代码结构.函数导航,代码高亮等都不支持,使用很不便.下面介绍下我发现的几个VS2010插件,具有哪些功能,如何安装和使 ...
- C#------SortedLIst键值对的使用方法
方法: SortedList sf = new SortedList(); sf.Add(, "广州"); sf.Add(, "江门"); sf.Add(, & ...
- 第十二章:Linux中权限控制实例
前言 前文对 Linux 中的权限进行了较为透彻的分析.而本文,则在前文的基础上,具体说明如何在代码中进行权限控制. 下面的代码涉及到以下几个方面: 1. 创建文件时设置文件权限 2. 修改文件的默认 ...
- weX5如何绑定KO对象
define(function(require){ var $ = require("jquery"); var justep = require("$UI/system ...
- HTML-网页常见错误
400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无法重复此请求. HTTP 错误 401 401.1 未授权:登录失败 此错误表明传输给服务器的证书与登录服务器所 ...
- Codeforces Round #190 (Div. 2).D
一道贪心题. 可以分两种情况 1 .是没有把对面的牌全打败,那么只要用最大的可能去打攻击状态的牌. 2. 是将对面的牌全打败,那么只要保证打对面防守状态的花费最小,就可以保证最后的结果最大 两种情况下 ...