`
javawebsoa
  • 浏览: 437075 次
社区版块
存档分类
最新评论

Java学习笔记:(34)必要时进行保护性拷贝

 
阅读更多
虽然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
Java代码 收藏代码
  1. packageenhance_chapter7;
  2. publicclassItem39_Person{
  3. privateStringname;
  4. publicStringgetName(){
  5. returnname;
  6. }
  7. publicvoidsetName(Stringname){
  8. this.name=name;
  9. }
  10. publicItem39_Person(Stringname){
  11. super();
  12. this.name=name;
  13. }
  14. publicItem39_Person(){}
  15. }

再创建一个经理类:
Java代码 收藏代码
  1. packageenhance_chapter7;
  2. publicclassItem39_Manager{
  3. privatefinalItem39_Personperson;
  4. publicItem39_PersongetPerson(){
  5. //returnthis.person;
  6. //(2)对可变域的访问方法,只返回可变域的保护性拷贝(clone)。
  7. returnnewItem39_Person(person.getName());
  8. }
  9. publicItem39_Manager(Item39_Personperson){
  10. //this.person=person;
  11. //(1)保护性拷贝对构造函数的可变参数进行保护性拷贝
  12. //生成一个新的实例,和Test中的person不是同一个对象,则修改不影响this.person的值
  13. this.person=newItem39_Person(person.getName());
  14. }
  15. @Override
  16. publicStringtoString(){
  17. return"Manager:"+this.person.getName();
  18. }
  19. }

测试:
Java代码 收藏代码
  1. packageenhance_chapter7;
  2. publicclassItem39_Test{
  3. /**
  4. *@paramargs
  5. */
  6. publicstaticvoidmain(String[]args){
  7. Item39_Personperson=newItem39_Person();
  8. person.setName("liangfeng366");
  9. Item39_Managermanager=newItem39_Manager(person);
  10. System.out.println(manager);
  11. //攻击(1)
  12. person.setName("liangfeng");
  13. System.out.println(manager);
  14. //攻击(2)
  15. manager.getPerson().setName("liangfeng");
  16. System.out.println(manager);
  17. }
  18. }

分享到:
评论

相关推荐

    教你如何将java代码拷贝到有道云笔记

    而将Java代码整理后存入有道云笔记的过程,既可以帮助开发者整理学习和工作中的代码,也能便于和其他开发者分享交流。 在这个过程中,首先需要使用一个能够处理和格式化代码的工具,如在线代码高亮工具,它能够将...

    java笔记 java笔记

    - **简单性**:Java语言设计简洁明了,易于学习和使用。 - **健壮性**:Java拥有严格的错误检测机制,有助于开发健壮的应用程序。 #### 1.2 运行原理 Java程序的运行分为几个阶段: 1. **编写**:使用文本编辑器...

    Java入门学习笔记

    ### Java入门学习笔记 #### 一、Java特点与运行原理 **1.1 Java特点** - **简单性:** Java的设计使得它易于学习且避免了许多传统编程语言中存在的复杂性。 - **面向对象:** Java是一种纯面向对象的语言,支持...

    java2核心技术学习笔记

    Java 2核心技术学习笔记主要涵盖了面向对象编程的基本概念和核心机制。以下是对这些知识点的详细说明: 1. **封装**:封装是面向对象编程的重要原则,它禁止直接访问类的实例字段,而是通过对象的方法来操作数据。...

    springboot学习笔记

    ### Spring Boot 学习笔记知识点总结 #### 一、Spring 的发展历程 1. **Spring 1.x 时代:** - 特征:主要通过 XML 文件来管理 Bean 的声明周期和依赖关系。 - 实践问题:随着项目规模的增长,XML 配置变得异常...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...

    设计模式资料

    C++和Java都支持对象的深拷贝和浅拷贝。 6. **适配器模式**:将一个类的接口转换成客户希望的另一个接口。适配器使原本由于接口不兼容而不能一起工作的那些类可以一起工作。 7. **装饰器模式**:动态地给一个对象...

Global site tag (gtag.js) - Google Analytics