Making an object immutable when passed as a parameter

Can I make the object immutable when passed as a parameter, so that the called method cannot change it, but the called can?

So, I have something like this:

Class Car { Wheel wheel_1; Axis axis = new Axis(wheel_1); } Class Wheel { int size; setSize(int size) {} int getSize() {} } 

Now I am building a car with a wheel. Then from the car class I want to build an axis.

To do this, I pass wheel_1 to the axis constructor.

Now my question is: can I somehow take care that the Axis constructor does not resize wheel_1, but a cool car can change it.

+4
source share
6 answers

Yes. This is usually done using the copy-constructor for the Wheel class.

For instance:

 wheel_1 = new Wheel(wheel); 

Remember that the Wheel class must be written in a way that supports this. That is, he should either offer a copy constructor.

Note: this did not make the object immutable . He simply created a copy that cannot be edited by anything other than your class.

If you return an instance of Wheel from any of your other methods, be sure to protect it at the output:

 Wheel getWheel() { return new Wheel(wheel_1); } 

Finally, it is worth mentioning that it is always useful to create immutable classes whenever you can. So maybe you can avoid this problem by making Wheel immutable?

+4
source

Make the Wheel class immutable. Then let the Car object create a new Wheel object when it needs a new size.

 public final class Wheel { private final int size; public Wheel(int size) { this.size = size; } public int getSize() { return size; } } 

Now you can easily transfer the wheel object to the axis.

 public class Car { private Wheel wheel; private Axis axis; public Car(int initialWheelSize) { wheel = new Wheel(initialWheelSize); axis = new Axis(wheel); } } 
+5
source

Pass a copy of wheel_1 Axis wheel_1 .

 class Car { Wheel wheel_1; Axis axis = new Axis(new Wheel(wheel_1)); } 

In addition, Wheel will need a constructor that takes another Wheel object and copies its properties.

+3
source

Why don't you send this parameter as your superclass that does not have the setSize () method

 Class Car { Superwheel wheel_1; Axis axis = new Axis(wheel_1); } class Superwheel { int size; int getSize() {} } Class Wheel extends Superwheel{ int size; setSize(int size) {} int getSize() {} } 
+2
source

I would use the Wheel interface, which has only access methods, that is: -

Example

 interface WheelInterface { int getSize(); } class Wheel implements WheelInterface { // methods } class Axis { public Axis(WheelInterface wheel) { // Only getSize will be available } } 

Now just pass WheelInterface instead of Wheel, and only the constructors of your Axis class will only have access methods available.

Benefits

The advantages of this are the absence of the need for copying; you just provide the contract to the Axis class, and this contract says that it can only get the size, not change it.

Passing the same object reference by value, you do not need to call any copy constructor and do not have to worry about deep and shallow copy semantics. I would not want to use Clone on my wheel, I think it is a little dirty for the reasons mentioned in the comments to other answers.

In an object-oriented template, using an interface to abstract away from what you don't need is also a sign of good design. If your wheel has winter tires, your Axis class probably doesn't even need to be taken care of!

disadvantages

As already mentioned, you can return the interface back to a specific type (as others mentioned, assuming that you know what you are driving towards); this is called downcasting, and I do not recommend it; if this were done in a similar scenario, he probably would not have passed the code check.

+2
source

Yes, you can. If you make a car and a wheel in the same package and declare the wheel fields to be protected. Thus, Axis, if it is declared in another package, cannot access the Wheel setters, thereby making the wheel unchanged from the point of view of Axis.

Well, this decision is basic to begin with. Of course, you can think about whether to make the Wheel final or not, cloning, serializable, etc., Based on what level you want to make unchanged.

+1
source

All Articles