A mutable object is simply an object which can change its state after
construction.
For example, StringBuilder
and Date
are
mutable objects, while String
and Integer
are immutable objects
.
A class may have a mutable object as a field.
There are two possible
cases for how the state of a mutable object field can change :
-
its state can be changed only by the native class - the native class creates
the mutable object field, and is the only class which is directly aware of its existence
-
its state can be changed both by the native class and by its callers
- the native class simply points
to a mutable object which was created
elsewhere
Both cases are valid design choices, but you must be aware of which one
is appropriate for each case.
If the mutable object field's state should be changed only by the native
class, then a defensive copy
of the mutable object must
be
made any time it is passed into (constructors and set
methods) or out of
(get
methods) the class.
If this is not
done, then it is simple for the
caller to break encapsulation, by changing the state of an object which is simultaneously visible
to both
the class and its caller.
Example
Planet
has a mutable object field fDateOfDiscovery
,
which is defensively copied in all constructors, and in getDateOfDiscovery
.
Planet
represents an immutable class, and has no set methods for its fields.
Note
that if the defensive copy of DateOfDiscovery
is not made, then
Planet
is no longer immutable!
import java.util.Date;
/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {
public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}
/**
* Returns a primitive value.
*
* The caller can do whatever they want with the return value, without
* affecting the internals of this class. Why? Because this is a primitive
* value. The caller sees its "own" double that simply has the
* same value as fMass.
*/
public double getMass() {
return fMass;
}
/**
* Returns an immutable object.
*
* The caller gets a direct reference to the internal field. But this is not
* dangerous, since String is immutable and cannot be changed.
*/
public String getName() {
return fName;
}
// /**
// * Returns a mutable object - likely bad style.
// *
// * The caller gets a direct reference to the internal field. This is usually dangerous,
// * since the Date object state can be changed both by this class and its caller.
// * That is, this class is no longer in complete control of fDate.
// */
// public Date getDateOfDiscovery() {
// return fDateOfDiscovery;
// }
/**
* Returns a mutable object - good style.
*
* Returns a defensive copy of the field.
* The caller of this method can do anything they want with the
* returned Date object, without affecting the internals of this
* class in any way. Why? Because they do not have a reference to
* fDate. Rather, they are playing with a second Date that initially has the
* same data as fDate.
*/
public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}
// PRIVATE //
/**
* Final primitive data is always immutable.
*/
private final double fMass;
/**
* An immutable object field. (String objects never change state.)
*/
private final String fName;
/**
* A mutable object field. In this case, the state of this mutable field
* is to be changed only by this class. (In other cases, it makes perfect
* sense to allow the state of a field to be changed outside the native
* class; this is the case when a field acts as a "pointer" to an object
* created elsewhere.)
*/
private final Date fDateOfDiscovery;
}
分享到:
相关推荐
防御式编程 Defensive Programming.PPT完整版(精品课件) 大纲: 保护程序免遭非法输入数据的破坏 断言 错误处理技术 异常 隔离程序 辅助调试代码
防御性驾驶指南Guide_For_Defensive_Drivind
本讲讨论了操作系统防御性第一部分的知识点,包括操作系统的防御机制、kernel mode和user mode、RISC-V架构、Supervisor mode、Page Table、虚拟内存、Bug和漏洞、Defensive Programming等内容。这些知识点对于理解...
### 防御性数据库编程与SQL Server #### 引言 《防御性数据库编程与SQL Server》一书由Alex Kuznetsov撰写,并由Hugo Kornelis进行了技术审稿,首次由Simple Talk Publishing出版于2010年。本书主要探讨了在SQL ...
SAS防御性编程和错误检查关键字:sas sql连接合并合并大数据分析宏oracle teradata mysql sas社区stackoverflow统计信息人工智慧AI Python R Java Javascript WPS Matlab SPSS Scala Perl CC#Excel MS Access JSON...
虽然C语言和Unix API在设计上存在一定的安全缺陷,但通过采取适当的防御性编程策略,仍然可以编写出安全可靠的程序。Ulrich Drepper在其著作中不仅指出了这些常见的问题,还给出了实用的解决方案。对于那些希望提高...
本书《Defensive Database Programming with SQL Server》由Alex Kuznetsov撰写,深入探讨了如何在SQL Server环境中实施防御性编程策略。 ### 一、基本防御性数据库编程技术 #### 1. 减少代码漏洞 - **定义假设**...
* 防御性因子择时(Defensive Factor Timing)是一种投资策略,积极主动地使用市场信号预判因子未来风险,并降低预期出现风险的因子的敞口或组合的整体风险水平。 * 这种策略可以帮助投资者在市场风险较高时,降低...
Defensive Security Handbook: Best Practices for Securing Infrastructure by Lee Brotherston English | 3 Apr. 2017 | ASIN: B06Y18XC5Y | 268 Pages | AZW3 | 3.88 MB Despite the increase of high-profile ...
詹妮弗·厄本(Jennifer Urban)和杰森·舒尔茨(Jason Schultz)提出了防御性专利许可(“原始DPL”)。 原始DPL本质上是一种标准化的,网络化的,未经协商的,范围广泛的,免版税的专利交叉许可。 原始DPL充分利用...
Java防御性编程是一种编程策略,旨在提前预防程序中可能的错误和异常,从而提高软件的稳定性和可靠性。在Java中,防御性编程通常通过注释、异常处理、数据验证和健壮的错误处理来实现。开源社区提供了许多工具和库来...
本书聚焦于防御性编程技术,旨在帮助数据库开发者预见到可能的问题,并采取措施避免或减轻这些问题的影响。 ### 防御性数据库编程的核心理念 #### 减少代码脆弱性 防御性编程首先要求程序员对代码的运行环境有...
内容简介: Despite the increase of high-profile hacks, record-breaking data leaks, and ransomware attacks, many organizations don’t have the budget to establish or outsource an information security ...
Despite the increase of high-profile hacks, record-breaking data leaks, and ransomware attacks, many organizations don’t have the budget to establish or outsource an information security (InfoSec) ...
The practice of defensive school psychology THE PRACTICE OF DEFENSIVE SCHOOL PSYCHOLOGY DONALD A. LUPIANI Riverdale Country School Recent legal developments promise to bring school ...
9. **防御性拷贝**: 当接收可能被修改的外部对象时,可以创建该对象的一个副本,避免外部修改影响到内部逻辑。 10. **日志记录**: 适当地使用日志记录,可以帮助调试和追踪程序的运行状态,尤其是在发生错误时...
防御性投资这是一个脚本,它将分析股票以确定它是否是一个良好的购买机会。 股票评估的标准是基于本杰明·格雷厄姆(Benjamin Graham)的《聪明的投资者》(The Intelligent Investor)一书中的建议,该书在1973年...