copying: deep vs shallow copy module (clone() traps, copy constructors, serialization copy, records, defensive copies, collection copies), 17 contract tests
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b4X2xx7RrveVQU9R1N
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# copying
|
||||
|
||||
Companion code for the ankurm.com post *"Deep Copy vs Shallow Copy in Java: clone(), Copy Constructors, Serialization and Records."*
|
||||
Module in `java-core-examples`, the Java-core series. There is no `docs/` folder: the deeper material lives in the post itself, inside its expandable sections.
|
||||
|
||||
## Versions this was built and tested against
|
||||
|
||||
| Component | Version | Notes |
|
||||
|---|---|---|
|
||||
| JDK | 25.0.5+8 (Temurin, LTS) | Records, `List.copyOf`, `Arrays.copyOf`. |
|
||||
| JUnit Jupiter | 5.11.0 | Same as the sibling modules. |
|
||||
| Maven | 3.9.11 | |
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
export JAVA_HOME=/path/to/jdk-25
|
||||
mvn compile
|
||||
scripts/run.sh CloneDemo # one demo
|
||||
scripts/broken.sh # the deliberate compile error
|
||||
scripts/run-all.sh # regenerate every file in output/
|
||||
```
|
||||
|
||||
## What's in here
|
||||
|
||||
| File | What it shows |
|
||||
|---|---|
|
||||
| `ShallowVsDeepDemo.java` | Assignment vs shallow copy vs deep copy on one `Person` graph. |
|
||||
| `CloneDemo.java` | `clone()` skips the constructor, is shallow, needs `Cloneable`, and a parent that uses `new` breaks subclasses. Arrays and `ArrayList.clone()` are shallow too. |
|
||||
| `src/broken/FinalFieldClone.java` | Does not compile: a `final` field cannot be deep-copied inside `clone()`. Not part of the Maven build. |
|
||||
| `CopyConstructorDemo.java` | Copy constructors with `final` fields, subtype slicing, and a virtual `copy()` that fixes it. |
|
||||
| `SerializationCopyDemo.java` | Deep copy via `ObjectOutputStream`: `transient` loss, shared references and cycles preserved, `NotSerializableException`. |
|
||||
| `RecordCopyDemo.java` | Records are only shallowly immutable: `List.copyOf` in the compact constructor, withers, a mutable `Date` component. |
|
||||
| `DefensiveCopyDemo.java` | Leaks through constructor and getter; `unmodifiableList` (view) vs `List.copyOf` (snapshot). |
|
||||
| `CollectionCopyDemo.java` | Every standard list, map and array copy is shallow; the deep versions. |
|
||||
| `CopyOfIdentityDemo.java` | When `List.copyOf` returns the same instance and when it copies; null elements. |
|
||||
| `CopyCostDemo.java` | Indicative cost of copy constructor vs `clone()` vs serialization. Timing: results drift per run. |
|
||||
| `CopyingTest.java` | Pins every claim above as an assertion (17 tests). |
|
||||
| `output/01-11` | Captured runs of everything above. `10-cost.txt` is the only non-deterministic file. |
|
||||
|
||||
## License
|
||||
MIT - see [LICENSE](../LICENSE).
|
||||
Reference in New Issue
Block a user