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)
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With