java:immutable-objects
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
java:immutable-objects [2023/04/08 01:17] – odefta | java:immutable-objects [2023/07/04 19:36] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 7: | Line 7: | ||
* **Thread safety**: they cannot change its state, so they cannot be corrupted by thread interference or observed in an inconsistent state. | * **Thread safety**: they cannot change its state, so they cannot be corrupted by thread interference or observed in an inconsistent state. | ||
* **Atomicity of failure**: if an immutable object throws an exception, it's never left in an undesirable or indeterminate state. | * **Atomicity of failure**: if an immutable object throws an exception, it's never left in an undesirable or indeterminate state. | ||
- | * **Protection against null reference | + | * **Predictability**: |
+ | * **Validity**: is not needed to be tested again and again. Once we create the immutable object and test its validity once, we know that it will be valid indefinitely. | ||
===== Disadvantages ===== | ===== Disadvantages ===== | ||
Line 19: | Line 20: | ||
* make copies of caller provided data (except primitives or immutable objects) | * make copies of caller provided data (except primitives or immutable objects) | ||
* ensure the class cannot be overridden (make the class final, or use static factories and keep constructors private) | * ensure the class cannot be overridden (make the class final, or use static factories and keep constructors private) | ||
+ | * don't provide setter methods for variables. | ||
+ | ===== Example of immutable class ===== | ||
+ | <code java> | ||
+ | import java.util.ArrayList; | ||
+ | import java.util.List; | ||
+ | final class Record { | ||
+ | private final long id; | ||
+ | private final String name; | ||
+ | private final List< | ||
+ | |||
+ | public Record(long id, String name, List< | ||
+ | this.id = id; | ||
+ | this.name = name; | ||
+ | |||
+ | /* This works, but: | ||
+ | - it will always duplicate elements | ||
+ | - the same copy should be used also in getTokens() method. | ||
+ | */ | ||
+ | // | ||
+ | |||
+ | /* If tokens is already unmodifiable (for ex. was formed using List.of), | ||
+ | then it will not duplicate elements. | ||
+ | Also, it will prevent the tokens to be modified | ||
+ | (it will throw java.lang.UnsupportedOperationException). | ||
+ | */ | ||
+ | this.tokens = List.copyOf(tokens); | ||
+ | } | ||
+ | |||
+ | public long getId() { | ||
+ | return id; | ||
+ | } | ||
+ | |||
+ | public String getName() { | ||
+ | return name; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * No simple setters, return another copy of the object. | ||
+ | * @param name | ||
+ | * @return Record | ||
+ | */ | ||
+ | public Record withName(String name) { | ||
+ | return new Record(id, name, tokens); | ||
+ | } | ||
+ | |||
+ | public List< | ||
+ | //return new ArrayList<> | ||
+ | return tokens; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public String toString() { | ||
+ | return " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class TestRecord { | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | List< | ||
+ | tokens.add(" | ||
+ | tokens.add(" | ||
+ | |||
+ | Record record = new Record(1, " | ||
+ | System.out.println(record); | ||
+ | |||
+ | tokens.remove(0); | ||
+ | System.out.println(record); | ||
+ | |||
+ | System.out.println(record.withName(" | ||
+ | |||
+ | record.getTokens().add(" | ||
+ | System.out.println(record); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | Output: | ||
+ | < | ||
+ | Record (id = 1, name=' | ||
+ | Record (id = 1, name=' | ||
+ | Record (id = 1, name=' | ||
+ | Exception in thread " | ||
+ | at java.base/ | ||
+ | at java.base/ | ||
+ | at ro.medjava.immutability.TestRecord.main(Record.java: | ||
+ | </ | ||
+ | |||
+ | ===== Immutable classes in JDK ===== | ||
+ | Some immutable classes from java api: | ||
+ | * java.lang.String | ||
+ | * java.lang.Integer | ||
+ | * java.io.File | ||
+ | * java.util.Locale | ||
+ | * java.awt.Font | ||
+ | * java.net.InetSocketAddress | ||
+ | |||
+ | <note tip> | ||
+ | Immutable classes can also be created using builder pattern. | ||
+ | Builder Pattern is a better option if the immutable class has a lot of attributes and some of them are optional.</ | ||
java/immutable-objects.1680905876.txt.gz · Last modified: 2023/07/04 19:36 (external edit)