Abhishek Jain
Abhishek Jain

Reputation: 4518

Is there a way to fix the value of an object as constant in java?

We know that the final keyword creates a constant reference to an object. For example:

final Object object = new Object();

However, in this case , only the reference to the object is fixed and cannot be changed during the execution runtime of the program. I may still call setter methods on this object and alter the values of its data members. Is there a way I can prevent this in Java (equivalent of const in C++) ?

I understand a way where I should not define setters to this object class or should allow setting of values only once, but what if I want to pass this object as an argument to a function and do not want that function to alter values of this object's data members. I may still want to alter the values outside the function.

What should be the function prototype in that case?

Upvotes: 1

Views: 182

Answers (4)

AlexR
AlexR

Reputation: 115328

You have several solutions.

  1. First you can solve it by design. Create interface that does not have methods that can modify the object state. For example it will contain getters only. Now the variable type is interface. Client will not be able to modify the state.
  2. If your class implements interface you can wrap it using dynamic proxy that prevents calling setters. BTW if you you class is actually collection or map you can use Collections.unmodifireableMap() or Collections.unmodifireableList() to make it indeed unmodifireable.
  3. You can use byte code engineering. This will work even if your class does not implement any interface. There are 2 ways to do this. Libraries like javassist and cglib allow creating dynamic proxy that wrap concrete class. So, you can wrap your object using proxy created utilizing one of these libraries. The proxy will throw exception when setter is called.
  4. Use byte code modification at compile time. For example AspectJ can help you.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726559

The trick is to define a read-only interface to the object, and put the setters only into the class, like this:

public interface ConstInterface {
    int getFirst();
    String getSecond();
}

public class MutableClass implements ConstInterface {
    private int _first;
    private String _second;
    int getFirst() {
        return _first;
    }
    void setFirst(int f) {
        _first = f;
    }
    String getSecond() {
        return _second;
    }
    void setSecond(String s) {
        _second = s;
    }
}

final ConstInterface obj = new MutableClass();

At this point, you can access obj as read-only through its interface. If you need to set properties, cast obj to MutableClass, and call the setters.

Upvotes: 4

Tim Bender
Tim Bender

Reputation: 20442

Another option is to create a delegate which overrides all of the methods which will change the objects state and instead throw an exception or performs a no-op.

Upvotes: 0

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

but what if I want to pass this object as an argument to a function and do not want that function to alter values of this object's data members. I may still want to alter the values outside the function.

In that case, you should just pass a clone of the object instead of the object itself to the method.

Upvotes: 3

Related Questions