It is stated in the specifications and the requiremnets of the project, that
Id of Product should not be changeable..it is of type
Long
Does it mean, it must be immutable? If yes, how to check for immutability of an object programmatically?
It is stated in the specifications and the requiremnets of the project, that
Id of Product should not be changeable..it is of type
Long
Does it mean, it must be immutable? If yes, how to check for immutability of an object programmatically?
does it mean, it must be immutable?
Yes, "not changeable" and "immutable" are synonyms.
how to check immutability or not of an object
(see below for updated answer for updated question)
By looking at its documentation and API of the object's class. If it doesn't provide any mutation operations (setters, etc.), then the object is immutable. The class would also need to be final
or have no protected
fields, since otherwise you could subclass it and modify the protected fields.
Long
is immutable, for instance (unless you use reflection to break into a specific implementation). If you look through its method list, it doesn't provide any mutator operations, and it's a final
class.
After this answer was posted, you modified the question to:
how to check immutability or not of an object programmatically
I don't think you can. There's nothing in reflection that tells you whether a method is a mutator or not, and it would be extremely unreliable to make assumptions based on method names. Of course, if the object's class is final
and offers no instance methods at all, that probably means it's immutable. But lots of immutable classes have instance methods (including Long
).
Yes you can determine whether an object is immutable. However, it is very complicated business, so a solution would not fit within an answer here on Stack Overflow.
There are two approaches to determine whether a class is immutable:
An existing static analysis tool is MutabilityDetector at https://github.com/MutabilityDetector.
An existing runtime checking tool is Bathyscaphe at https://github.com/mikenakis/Bathyscaphe (I am the author.)
In my opinion, static analysis can be useful at certain times and under certain scenarios, but it does not provide a complete solution to the problem at all times. A complete solution requires runtime checking as I explain on my blog here: https://blog.michael.gr/2022/05/bathyscaphe.html, and that's why I have written Bathyscaphe.
The issue is not whether 'Long' is immutable; the issue is whether the the id of a 'Product' is immutable.
You provide immutability of the id by making the id field private, by not implementing any method that will change the id, and by not writing any code in the Product class that changes the id.
Why isn't the immutability of Long relevant? Consider this example that fails to meet your requirement that the id should not be changeable:
class Product {
private Long id;
Product() { id = 42; }
Long getId() { return id; }
void setId(Long newId) { id = newId; }
:
}
All of those Longs are themselves immutable, but the product id changes nevertheless: because setId
assigns a different immutable Long value to the id member.
However, if you just delete that setId
method (and don't write anything similar in the Product class) then the product id is now not changeable.
how to check immutability or not of an object programmatically?
We can't. Moreover I don't feel this must be done programmatically. Read further,
Let's have an imaginary Exception
class as below,
public class MutationOfImmutableException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public MutationOfImmutableException(String string) {
super(string);
}
}
And our class (I can't think of a great name, but I guess this conveys the idea) have
public void setName(String name) throws MutationOfImmutableException {
throw new MutationOfImmutableException("Cannot mutate this immutable instance");
}
And, in our main class, whenever someone calls setName()
by mistake, the compiler warns us to handle the Exception properly.
p.setName("Anees"); // Cannot do this until handled!
In short, if you have access to the class Product
which is immutable, you can throw a Checked Exception from setId()
, to avoid everything going haywire!
Better still, make your setters
private so that you cannot even encounter this scenario.