Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any nice way to make two immutable objects refer to eachother?

Take these two Java classes:

class User {
   final Inventory inventory;
   User (Inventory inv) {
       inventory = inv;
   }
}

class Inventory {
   final User owner;
   Inventory (User own) {
       owner = own;
   }
}

Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.

Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.

(* Because reflection may give trouble with a security manager)

(** Says my limited knowledge)

like image 976
Bart van Heukelom Avatar asked Nov 02 '11 10:11

Bart van Heukelom


People also ask

How would you make an immutable class with mutable references like a list?

Make all fields private so that direct access is not allowed. Do not provide setter methods (methods that modify fields) for variables, so that it can not be set. Make all mutable fields final so that their values can be assigned only once. Initialize all the fields through a constructor doing the deep copy.

What does it mean by saying immutable objects?

In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created.

Which objects should be called immutable?

The immutable objects are objects whose value can not be changed after initialization. We can not change anything once the object is created. For example, primitive objects such as int, long, float, double, all legacy classes, Wrapper class, String class, etc. In a nutshell, immutable means unmodified or unchangeable.


1 Answers

This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):

class User {
   private final Inventory inventory;
   User () {
       inventory = new Inventory(this);
   }
}

You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!

Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.

Delving deeper into the issue, I found§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.

like image 149
Joachim Sauer Avatar answered Oct 14 '22 16:10

Joachim Sauer