今天看了这一张模模糊糊的,有点晕。找了几篇播客,终于看懂了。
http://tonylian.iteye.com/blog/391256
http://hi.baidu.com/dongbomoo/blog/item/372cf18a17c4a8789e2fb42d.html
虽然java程序是一门安全的语言(safe language)。但即使在安全语言中,如果不采取一些措施,还是无法使自己与其他的类隔离开。假设类的客户会尽一切手段来破坏这个类的约束条件,在这样的前提下,你必须保护性地设计程序。所以说,从安全的角度考虑,应该设计面对客户的不良行为时仍能保持健壮性的类,无论系统的其它部分发生什么事情,这些类的约束都可以保持为真。
为保护实例的内部信息免受攻击,对构造函数的每个可变参数进行保护性拷贝是必要的。并且使用拷贝之后的对象作为实例的组件,而不使用原始对象。
例如,写了雇员这个类。我自己用的时候对其属性做一些改动稍后会被我的程序提交到后台数据库。但是前端的人员和我做接口的时候,一些查询方法需要雇员对象。但是我不想让他们对这个雇员的属性做修改后也被提交到后台数据库。
所以我可以给他们的对象都是我自己对象的拷贝。他们即使调用这个对象的一些方法改变对象的属性。后面也不会被我的程序提交到后台数据库。
http://topic.csdn.net/u/20080301/20/f0ce18e9-2fc7-4f75-9058-67a8496cc8c7.html
Effective Java》保护性拷贝无非就两条原则:
一、对构造函数的可变参数进行保护性拷贝;
二、对可变域的访问方法,只返回可变域的保护性拷贝(clone)。
什么叫不可变类?如果某个类,当创建了这个类的实例后,就不允许修改它的属性值,那么它就是不可变类。如:java.lang.String 就是一个典型的不可变类创建一个不可变类可按如下步骤:
1.把属性定义为private final类型。
2.不对外公开用于修改属性的setXXX()方法。
3.只对外公开用于读取属性的getXXX()方
以下是对播客例子中的一个修改:
创建一个可变类:Item39_Person
package enhance_chapter7;
public class Item39_Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Item39_Person(String name) {
super();
this.name = name;
}
public Item39_Person() {}
}
再创建一个经理类:
package enhance_chapter7;
public class Item39_Manager {
private final Item39_Person person;
public Item39_Person getPerson() {
//return this.person;
//(2)对可变域的访问方法,只返回可变域的保护性拷贝(clone)。
return new Item39_Person(person.getName());
}
public Item39_Manager(Item39_Person person){
//this.person = person;
//(1)保护性拷贝 对构造函数的可变参数进行保护性拷贝
//生成一个新的实例,和Test中的person不是同一个对象,则修改不影响this.person的值
this.person = new Item39_Person(person.getName());
}
@Override
public String toString() {
return "Manager:" + this.person.getName();
}
}
测试:
package enhance_chapter7;
public class Item39_Test {
/**
* @param args
*/
public static void main(String[] args) {
Item39_Person person = new Item39_Person();
person.setName("liangfeng366");
Item39_Manager manager = new Item39_Manager(person);
System.out.println(manager);
//攻击(1)
person.setName("liangfeng");
System.out.println(manager);
//攻击(2)
manager.getPerson().setName("liangfeng");
System.out.println(manager);
}
}
分享到:
相关推荐
可以对制定文件夹进行选择性拷贝,用以解决了某些ide无法增量打包的问题
快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高80%)快速拷贝软件(拷贝速度提高...
深拷贝和浅拷贝一些例子
深拷贝拷贝的是内容,浅拷贝拷贝的是指针。学习笔记分享。
让你对C++的深拷贝和浅拷贝进一步了解,自己制作的,特和大家分享
利用io流编写的简单的文件拷贝小程序,可在控制台进行文件的拷贝.
js考虑最完善的深拷贝函数,可以深拷贝引用对象和基本对象
Android 文件拷贝Demo,可实现SD卡以及内部存储之间进行拷贝
3、无论是声明NSString还是NSMutableString类型的属性时,我们希望此属性被赋值为NSMutableString类型的字符串后,此属性不会因这个可变类型字符串的改变而改变(这也是多数情况下的用法),那就用copy修饰属性
聊到了多种深度拷贝方法,其中就提到了一种Lambda表达式拷贝的方法,这位同事说这种深度拷贝快是快但是如果对象里面再嵌入对象就不能深度拷贝了,只进行浅拷贝,我很疑惑,如果是这样设计的那这个深度拷贝还有什么...
由于内存的速度比CPU的速度慢得多, 在一些频繁进行 大块内存拷贝的程序中, 内存拷贝会消耗大量的时间, 从而严 重影响程序的性能。通常采用两种方法在现有CPU和内存的 条件下解决这个问题: 一是采用后台程序在CPU ...
2021-孕妇外周血浆胎儿游离DNA高通量测序筛查致病性拷贝数变异的技术标准共识.pdf
该例子代码主要实现C#的浅拷贝和深拷贝,深拷贝是通过复制对象和序列化对象两种方法分别实现的。各位同学各取所需。
通过简短的代码和图片来说明C++中深拷贝和浅拷贝的区别和概念。
使用windows api可以在VB中方便的进行内存的拷贝操作,这省去了很多反复的赋值操作,效率很高。在串口通信,协议转换一类的程序上尤其有用。
烂碟拷贝工具(绿色 强制性拷贝 电脑不能读碟的光盘
本人采用C++实现的string类,采用的内存管理策略是隐式共享写时拷贝,其实现参考了智能指针的思想。
在Python中,浅拷贝(shallow copy)和深拷贝(deep copy)是用于创建对象副本的两种常见方式。它们可以应用于不同类型的对象,如列表、字典、集合等。下面是对浅拷贝和深拷贝的描述: 浅拷贝:浅拷贝是创建一个新...
MFC文件拷贝程序MFC文件拷贝程序MFC文件拷贝程序
实现按文件的修改时间来筛选,将筛选出的文件拷贝到指定目录文件夹下。(源代码,直接运行) 将指定目录下的所有文件的修改时间大于或等于指定时间的文件拷贝到目标目录的文件夹下;只有指定目录文件夹下文件的修改...