"You should program defensively, assuming that your class's clients will do their best to destroy its invariants"
Java as a safe language:
- Java prevents common memory errors in C/C, but does not fully isolate classes from unwanted interactions with other classes.
- Defensive programming is required, assuming that clients of the class may attempt to violate its invariants.
Immutable classes and security:
- Example of class "Period" that appears immutable but can be corrupted due to the mutability of objects such as Date.
- Solution: Make defensive copies of mutable parameters when receiving them in the constructor.
public Period(Date start, Date end) {
this.start = new Date(start.getTime()); // Cópia defensiva
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0)
throw new IllegalArgumentException(start + " after " + end);
}
Copy after login
Defensive copies in builders:
- Defensive copies must be made before validating parameters to avoid vulnerabilities (e.g. TOCTOU attack).
- Avoid using clone() for defensive copies of potentially untrusted objects, preferring static constructors or factory methods.
Getters and mutability:
- Issue: Getters can expose mutable internal components, allowing external mutations.
- Solution: Getters should return defensive copies of mutable objects.
public Date getStart() {
return new Date(start.getTime()); // Cópia defensiva
}
Copy after login
Application to mutable classes:
- Defensive copying also applies to mutable classes that store references to client-supplied mutable objects.
- Example: When storing an object in a Set or Map, one must consider whether the object can be modified later.
Return of internal components:
- When returning mutable internals, consider returning defensive copies or immutable views.
Use of immutable objects:
- Whenever possible, use immutable objects as internal components to avoid the need for defensive copies.
Costs and alternatives:
- Defensive copies can impact performance; Alternatives include relying on documentation or clear usage agreements.
- In cases of explicit transfer of control, such as in design patterns (e.g. wrapper), defensive copy can be dispensed with.
Conclusion:
- Use defensive copies to protect the integrity of classes, except when the cost is impractical or mutual trust is established and clear documentation is required.
Examples from the book:
The above is the detailed content of Item Make defensive copies when necessary. For more information, please follow other related articles on the PHP Chinese website!