Java面试问题之十八
程序员文章站
2022-07-13 09:14:00
...
阅读以下代码段,结合代码的意图分析此代码是否能够实现这个目的。
问题分析:根据上述代码段可以看出,其意图是创建一个Schedule类,这个类包括了学校的开学时间和放假时间信息,并且想要其变成一个不可变类。但是,实际上这段代码并没有达到这个目的。它的开学时间和放假时间依然是可以被外部修改的。原因在于这个类没有实现保护性拷贝机制。在创建不可变类的时候,假定它的属性的类型是不可变类型,在必要的情况下,必须提供保护性拷贝,否则,这个不可变类实例的属性依然有可能被错误地修改。
为了保证Schedule对象的start属性和end属性值不会修改,这两个属性值必须使用保护性拷贝。例如:
通过采用保护性拷贝,其他程序无法获得与Schedule对象关联的两个Date对象的引用,因此也就无法修改这两个Date对象的属性值。
另外,如果Schedule类中被final修饰的属性所属的是不可变类,就没有必要提供保护性拷贝机制了,因为该属性所引用的实例的值永远都不会被改变。
import java.util.Date; public final class Schedule { private final Date start; //开学时间,不允许被修改 private final Date end; //放假时间,不允许被修改 public Schedule(Date start,Date end){ if(start.compareTo(end)>0) throw new IllegalArgumentException(start+" after "+end); this.start=start; this.end=end; } public Date getStart(){ return start; } public Date getEnd() { return end; } }
问题分析:根据上述代码段可以看出,其意图是创建一个Schedule类,这个类包括了学校的开学时间和放假时间信息,并且想要其变成一个不可变类。但是,实际上这段代码并没有达到这个目的。它的开学时间和放假时间依然是可以被外部修改的。原因在于这个类没有实现保护性拷贝机制。在创建不可变类的时候,假定它的属性的类型是不可变类型,在必要的情况下,必须提供保护性拷贝,否则,这个不可变类实例的属性依然有可能被错误地修改。
为了保证Schedule对象的start属性和end属性值不会修改,这两个属性值必须使用保护性拷贝。例如:
import java.util.Date; public final class Schedule { private final Date start; private final Date end; public Schedule(Date start,Date end) { if(start.compareTo(end)>0) throw new IllegalArgumentException(start+" after "+end); this.start=new Date(start.getTime()); //采用保护性拷贝 this.end=new Date(end.getTime()); //采用保护性拷贝 } public Date getStart() { return (Date)start.clone(); //采用保护性拷贝 } public Date getEnd() { return (Date)end.clone(); //采用保护性拷贝 } }
通过采用保护性拷贝,其他程序无法获得与Schedule对象关联的两个Date对象的引用,因此也就无法修改这两个Date对象的属性值。
另外,如果Schedule类中被final修饰的属性所属的是不可变类,就没有必要提供保护性拷贝机制了,因为该属性所引用的实例的值永远都不会被改变。
上一篇: MybatisPlus的相关操作
下一篇: 搜索功能(五)03-搜索关键字历史重复记录-数组去重操作——es6 set类数组-数据结构-数组去重 & 三个点(...)方法-对象的延展操作-拆解数组
推荐阅读
-
Java常见面试问题: equals()与hashCode()的使用
-
Java面试题必备知识之ThreadLocal
-
大厂面试手撕源码之java数组拷贝
-
js前端面试之同步与异步问题详解
-
Java学习笔记十八:Java面向对象的三大特性之封装
-
Java面试题总结之数据库与SQL语句
-
【每日一道算法题】Leetcode之longest-increasing-path-in-a-matrix矩阵中的最长递增路径问题 Java dfs+记忆化
-
【java基础】面试常见问题:类和对象,封装继承多态,final关键字,static关键字,类加载过程,双亲委派模型
-
Java软件工程师面试常见问题集锦之一
-
Java面试题之int和Integer的区别