Skip to content

karolkrasnowski/ImmutableView

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ImmutableView lets you create an immutable version of your data structures at runtime

Why should I bother?

Immutable objects have a lot of benefits, some of them are listed below:

  • they are easier to test
  • they are thread-safe
  • their usage is side-effect free (no defensive copies)
  • there is no identity mutability problem
  • they are easier to cache

You can read more about it in this article.

Use case

Let's assume you are working with external code you cannot modify. Data structures in this code are mutable. In order to reduce the risk related to mutability you want to rewrite these data structures into your own immutable versions. It looks like a really tedious task, so perhaps there is another option? Indeed, you can make use of ImmutableView and enjoy all the benefits of immutability. It internally uses bytecode manipulation to intercept method invocations and add desired behaviour.

Usage

Let's assume you have an object person of class Person which looks like this:

class Person {

    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    int getAge() {
        return age;
    }

    void setAge(int age) {
        this.age = age;
    }
}

Let's initialize our mutable object:

Person person = new Person("John", 30);

In order to make an immutable version of this object just type:

Person immutablePerson = ImmutableView.of(person);

Now any mutator invocation will throw ImmutableObjectModificationException.

immutablePerson.setAge(43); // throws exception

ImmutableView assumes all void methods mutate the object state.

If instead of throwing an exception you just want to silently ignore the fact of object modification you can use:

Person immutablePerson = ImmutableView.silent.of(person);

Now any mutator invocation will be silently ignored.

immutablePerson.setAge(43);
immutablePerson.getAge(); // returns 30

ImmutableView works also for nested structures. To illustrate this let's add to the Person class field of type Address. Address class has in turn field of type Street.

class Address {

    private Street street;
    private String city;

    Address(Street street, String city) {
        this.street = street;
        this.city = city;
    }

    Street getStreet() {
        return street;
    }

    void setStreet(Street street) {
        this.street = street;
    }

    String getCity() {
        return city;
    }

    void setCity(String city) {
        this.city = city;
    }
}

class Street {

    private String name;
    private int number;

    Street(String name, int number) {
        this.name = name;
        this.number = number;
    }

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    int getNumber() {
        return number;
    }

    void setNumber(int number) {
        this.number = number;
    }
}

Well, let's create our person object:

Person person = new Person("John", 30, new Address(new Street("Spencer Park", 7), "London"));

and make it immutable:

Person immutablePerson = ImmutableView.of(person);

All nested properties became recursively immutable:

immutablePerson.getAddress().getStreet().setName("Trefoli Rd") // throws exception

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages