I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance. (Unfortunately, the fields cannot be final because they needs to be populated by Hibernate.)
This worked well until I wanted to check another class throws the correct exception when called with an invalid instance of the model. The constructor of the model validates the arguments so reflection must be used to set the fields. This is extremely clumsy since the model have quite a few fields and the field names have to be hard-coded.
I can't mock the model either due to it being final. (Is it also debatable whether an interface should be used to enable mocking while keeping the class immutable. By having an interface, there's no way to programmatically mandate the methods must return the same value throughout the life of the instance.)
What do people usually do in this case? Is there any standard approach to this?
Generally speaking, you shouldn't want to mock data objects. Data objects should have no logic and no external dependencies, so there's not really much use to mocking the objects. Instead make it very easy to create fake instances that you can populate in methods as you'd like.
Furthermore, there are a few other reasons you might want to avoid treating a Hibernate-persisted object as immutable:
Hibernate-provided objects are inherently not thread-safe and therefore lose the thread-safety advantages that immutable value objects typically provide.
You may find your objects are actually proxies, possibly undercutting the final semantics.
Hibernate-controlled objects operate completely differently whether their session is still open (attached vs detached) making them a very poor choice for an immutable object. If your immutable object depends on session lifetime, it's not really immutable.
It sounds like some objects may be valid or invalid at the application layer, beyond database-layer validation. That makes it a little harder to encapsulate your validation concerns.
You are required to have a public no-arg constructor, which is antithetical to the kind of instance control typical of immutable value objects.
Because the objects are inherently mutable, it is more complicated to override equals and hashCode.
My advice? If you need more immutability and data validation guarantees than a Hibernate DAO can grant you, then create a real final immutable class with final fields (or a private constructor and static factory method), and then make a constructor (or static factory method) that copies in values from your Hibernate DAO.
If you decide this option, you are stuck with the overhead of having two data objects that change roughly in parallel, but you also get the benefit of separating concerns (in case the Hibernate object should diverge) and the ease of a truly-immutable, equals-and-hashcode-overriding, session-agnostic, guaranteed-valid object that you can easily create for tests.
For clarity, making a class final prevents it from being sub-classed. This is good in cases where the class doesn't need to be further refined.
Marking a class level variable as final means that it will only get assigned once. For primitives and immutable objects like String, this has the side effect of making the variable immutable (by default).
However, for mutable objects like Date, your variable will always reference the same instance, but others with access to that instance would still be able to change it's state. For example if you had a method
public Date getCreatedDate(){
return this.created; // class variable declared as private final Date created...;
}
Then any caller could access the created instance and change it's state. You would be better to only return truly immutable values, or return a clone.
public Date getCreatedDate(){
return this.created.clone();
}
EDIT
"I marked an immutable data model class as final to make sure the only way to change its values is to create a new instance"
Your issue as I understand it is that Class A has a dependency on Class B. You wish to test class A and you are unable to mock class B, as you have marked it as final. You marked Class B as final to make it immutable (preventing it's internal state being changed). This is incorrect, as marking a class final prevents it from being sub-classed. It has nothing to do with the ability to change the internal state of an instance.
Your use of final does not have the desired effect. Marking the fields as final is not an option, and would not make the class immutable for the reasons stated above. The only way to protect your data is to prevent clients of your data from having access to the objects that make up it's internal state.
Assuming, that you won't be the only developer, you need to protect the users of your data from unintentional updates. Ensuring that you return clones from getters is one approach. Having team members sub-class and change data is just bad programming, not unintentional, and could be managed through policy and code review.
If you wish to protect your code from external interference by unknown developers (for example writing code that utilises the same namespace to inject their code), then other approaches are available such as package sealing.
Related
What is the benefit of making fields private while creating an immutable class?
I have seen why while creating immutable class, fields are declared as private? but I didn't get understand anything from this post.
Can anybody please explain me the same?
The best way to explain is with an example:
public class Immutable {
private final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Here we have a properly encapsulated, immutable class. Nothing can change the state (modulo nasty reflective tricks).
Now lets JUST change the access on the field:
public class Immutable {
public final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Note we are still making the defensive copy in getState ... as before ... but now someone can do this:
Immutable mu = new Immutable();
mu.state[1] = 'o';
... and our supposedly immutable object's state has changed.
That is ONE reason why it is a good idea to keep the fields private. (Obviously, this only applies to field whose types are mutable reference types.)
A SECOND reason is encapsulation. Declaring fields as private hides implementation details, which reduces the risk of unwanted cross-coupling. If I don't do this, then I (or some other programmer) might be tempted to write code that depends on the internals of Immutable. That is going to lead to problems if I need to change them; e.g. changing the type of state to String. Problems as in "lots more code to check / change".
A THIRD reason is that non-private (and particularly public) fields can be an impediment to subclassing. If I declare a field as public then, the I can't undeclare it in a subclass. If I want to hide the field or modify the behavior of the field in a subclass (by overriding) ... I can't. By contrast, if the field is private and access is via instance methods, I can override those methods in subclasses. Or I can choose to not use the field at all.
The only reason for making final fields private is binary compatibility, and this actually holds true irrespective of whether the containing class is immutable or not.
A class C is said to offer binary compatibility to classes X and Y
that use class C if class C can be refactored without having to
recompile classes X and Y.
You only need to worry about binary compatibility if you are developing a library to be used by software that is written by others and therefore you have no control over. If you are in this situation, then you pretty much have to use full encapsulation, which means that you have to make all fields private and only access them via getters.
However, in the vast majority of cases, what we are developing is top-layer, self-contained application software, not libraries to be used by others. So, in the vast majority of cases, there is no good reason to make final fields of immutable classes private, it is just a widely held misconception. In a top-layer, self-contained application scenario you can always refactor everything and your IDE will accordingly refactor all references, so immutable classes do not need encapsulation.
Some of the answers suggest that if a field is not private, and it points to a mutable object, then someone might go and modify that mutable object, which is of course correct, but then we go into the philosophical question of what really is an immutable object. Can an object still be called immutable if it contains mutable objects? Is the mutability of an object dependent on the mutability of objects that it contains?
My rule is as follows:
There are two kinds of fields: contained and referenced, which can otherwise be thought of as owned and unowned. As an example, think of an Employee class: the name of the employee is contained/owned by the class, since each employee has their very own name. However, the Employee class may also contain a reference to a Department class, and of course each employee does not have their very own department, so the department is a referenced/unowned field.
A contained/owned field like Employee.name must of course be final and immutable in order for the owning class (Employee) to be immutable. Such a field does not need to be private, unless we are aiming for binary compatibility.
A referenced/unowned field like Employee.department also needs to be final if the referring class (Employee) is to be immutable, but it does not have to be immutable, and its immutability does not affect the immutability of the referring class. Even in this case, (and unless we are aiming at binary compatibility,) a referenced/unowned field generally does not need to be private, because there is still no issue of encapsulation: we are not going to be making a defensive copy of an employee department, that would be nonsensical.
So, unless we are aiming for binary compatibility, then both in the case of contained/owned immutable fields and referenced/unowned fields (which can be either mutable or immutable,) the fields can stay public final and everything will be fine.
final class A{
final List l = new ArrayList();
}
Suppose you have list, and you made this list as final it's reference not modified at all.
But this list is easily accessible to outer classes and they are easily modify it's contents.
so prevent that we have to add private access specifier.
An object that is referred to by a public final reference-type field can still be modified through that field. (What you can't do is change the field to refer to a different object.)
To disallow unwanted modifications, you need to make the field private.
public fields can be accessed from any class anywhere and modified. But making fields private and final and using constructor injection / defensive copies, you ensure that the class is completely immutable.
Non-private fields may still be read-accessed - and if that field is an object, mutable operations on that object may be invoked.
Making the fields private will prevent this possibility.
If you'll use public field other objects will be able to change state of your "almost-immutable" object which will break encapsulation and make it a mutable object.
I'd like to create a few immutable objects for my codebase. What's the best way to really deliver the message that a given class is intended to be immutable? Should I make all of my fields final, and initialize during object construction? (This seems really awkward...) Should I create some Immutable interface, and have objects implement it? (Since Java doesn't have some standard interface behind this, I thought they had some other way of dealing with it.) What's the standard way this is dealt with? (If it's simply done by adding a bunch of comments around the fields exclaiming that they shouldn't be modified once initialized, that's fine too.)
Should I make all of my fields final, and initialize during object construction?
Yes. And ensure that those types are themselves immutable, or that you create copies when you return values from getter methods. And make the class itself final. (Otherwise your class on its own may be immutable, but that doesn't mean that any instance of your class would be immutable - because it could be an instance of a mutable subclass.)
(This seems really awkward...)
It's hard to know what to suggest without knowing how you find it to be awkward - but the builder pattern can often be useful. I usually use a nested static class for that, often with a static factory method. So you end up with:
Foo foo = Foo.newBuilder()
.setName("asd")
.setPoints(10)
.setOtherThings("whatever")
.build();
Yes and no. Making all fields final is not a guarantee in and of itself. If you'd like to get really in-depth with this there are a number of chapters in Effective Java by Joshua Bloch dealing with immutability and the considerations involved. Item 15 in Effective Java covers the bulk of it and references the other items in question.
He offers these five steps:
Don’t provide any methods that modify the object’s state (known as muta-
tors).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
Ensure exclusive access to any mutable components.
One way to learn how to do all of this is to see how the language designers make classes immutable by reviewing the source for classes like String which are immutable (for example see http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java).
Write a unit test that will fail if your coworkers make the class mutable.
Using Mutability Detector, you can write a test like this:
import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;
#Test public void isImmutable() {
assertImmutable(MyImmutableThing.class)
}
If a coworker comes along, and, for example, adds a setter method to your class, the test will fail. Your use case is one of the core purposes of Mutability Detector.
Disclaimer: I wrote it.
What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
Getter/Setter is the recommended way of accessing properties of an object. Otherwise you to have to use public properties, but public properties are not recommended.
If a classes' properties don't have getters and they are not visible (e.g. not public), that means that the class is designed so that you can't access them. In that case, there is no proper way to access them.
Flipping this around, if you are designing a class and you intend that other classes can access its attributes, you ought to provide getters. You could alternatively declare the attributes to be public, protected or package private, but that makes your abstraction leaky and has a number of undesirable consequences.
If you are asking how one of an object's methods should access its own attributes, the simple answer is whichever way is most convenient. If the class has getters, you could call them. Alternatively, you could just access the attributes directly. The problems of leaky abstraction don't apply in this case because the method accessing the state is inside the abstraction boundary.
This is mostly a matter of preference.
I personally prefer not to use the getters and setters in my object. This increases readability, allows me to change my getters and settings to return copies (of lists mostly) without it changing my own object. If you do something special in your getter then you can make a helper method that is used by both your getter and your other functions. This will go wrong if your classes get too large though (so don't make large classes). I don't like how using a getter setter hides the side effects inside the object (unlike for external users, they should be hidden from any side effects inside the object), when you want to have the side effects, give the private method a clear name indiciting it has them.
First off I'll answer the question as is:
What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
When you are within an object, you can reference the properties directly where the method is part of the object. For example:
public class testClass() {
public int x;
private someMethod() {
x = 4;
}
}
To answer the comment:
I think the question can be reformulated: Should I use getters and setters when implementing my object methods? Or should I access member variables directly?
You should always hide the internal data and other implementation details within a class as much as possible; seperating the API from the implementation (a.k.a encapsulation). Encapsulation decouples the modules thereby allowing them to be developed, tested and modified in isolation.
Generally, you should use the lowest access modifier possible (e.g. private, protected, package-private) whilst maintaining functionality for the application you're writing. The benefits of designing and devloping this way is that you can change implementation details without breaking code that uses the modules. If you make everything public, and other people are using your classes, you are forced to support it forever maintaining compatibility - or until they change their implementation that is using your modules.
Instance fields should never be public as you give up the ability to limit the values that can be stored in the field, and if it is a mutable object, you open your object up for misuse (see here). It is important to note too that classes with public mutable fields are not thread-safe. It is also important to note that instance fields that are declared public static final but are mutable objects can also be modified and can be a security risk.
Basically, in public classes - always use accessor methods, not public fields. It allows you to protect your mutable objects from modification outside of the class (be it intentionally or unintentionally) and allows you to change implementation detail later without harming your clients.
I want to make sure that a given group of objects is immutable.
I was thinking about something along the lines of:
check if every field is private final
check if class is final
check for mutable members
So I guess my question is: is 3. possible ?
I can check recursively whether every member of a class has its fields private final, but this is not enough since a class can have e method named getHaha(param) which adds the given param to an array for instance.
So is there a good way to check if an object is immutable or is it even possible ?
Thanks,
You may want to check out this project:
Mutability Detector
This library attempts to analyse the bytecode of a particular class, to discover if it is immutable or not. It allows testing for this condition in a unit test, as demonstrated in a video available here. It is certainly not perfect (a String field will be considered mutable, and your array example is not handled well) but it's more sophisticated than what FindBugs offers (i.e. only checking that every field is final).
Disclaimer: I wrote it ;-)
If you generate your data model and all its code, you can ensure the possible Data Value objects you create will be immutable to meet your needs.
The problem you have is that there is different forms of immutability. Even String would fail your test Are String, Date, Method immutable? You can prove that a class is strictly immutable this way, but you are likely to be better off generating your data model.
Yes, you can write an immutability detector.
First of all, you are not going to be just writing a method which determines whether a class is immutable; instead, you will need to write an immutability detector class, because it is going to have to maintain some state. The state of the detector will be the detected immutability of all classes which it has examined so far. This is not only useful for performance, but it is actually necessary because a class may contain a circular reference, which would cause a simplistic immutability detector to fall into infinite recursion.
The immutability of a class has four possible values: Unknown, Mutable, Immutable, and Calculating. You will probably want to have a map which associates each class that you have encountered so far to an immutability value. Of course, Unknown does not actually need to be implemented, since it will be the implied state of any class which is not yet in the map.
So, when you begin examining a class, you associate it with a Calculating value in the map, and when you are done, you replace Calculating with either Immutable or Mutable.
For each class, you only need to check the field members, not the code. The idea of checking bytecode is rather misguided.
First of all, you should not check whether a class is final; The finality of a class does not affect its immutability. Instead, a method which expects an immutable parameter should first of all invoke the immutability detector to assert the immutability of the class of the actual object that was passed. This test can be omitted if the type of the parameter is a final class, so finality is good for performance, but strictly speaking not necessary. Also, as you will see further down, a field whose type is of a non-final class will cause the declaring class to be considered as mutable, but still, that's a problem of the declaring class, not the problem of the non-final immutable member class. It is perfectly fine to have a tall hierarchy of immutable classes, in which all the non-leaf nodes must of course be non-final.
You should not check whether a field is private; it is perfectly fine for a class to have a public field, and the visibility of the field does not affect the immutability of the declaring class in any way, shape, or form. You only need to check whether the field is final and its type is immutable.
When examining a class, what you want to do first of all is to recurse to determine the immutability of its super class. If the super is mutable, then the descendant is by definition mutable too.
Then, you only need to check the declared fields of the class, not all fields.
If a field is non-final, then your class is mutable.
If a field is final, but the type of the field is mutable, then your class is mutable. (Arrays are by definition mutable.)
If a field is final, and the type of the field is Calculating, then ignore it and proceed to the next field. If all fields are either immutable or Calculating, then your class is immutable.
If the type of the field is an interface, or an abstract class, or a non-final class, then it is to be considered as mutable, since you have absolutely no control over what the actual implementation may do. This might seem like an insurmountable problem, because it means that wrapping a modifiable collection inside an UnmodifiableCollection will still fail the immutability test, but it is actually fine, and it can be handled with the following workaround.
Some classes may contain non-final fields and still be effectively immutable. An example of this is the String class. Other classes which fall into this category are classes which contain non-final members purely for performance monitoring purposes (invocation counters, etc.), classes which implement popsicle immutability (look it up), and classes which contain members that are interfaces which are known to not cause any side effects. Also, if a class contains bona fide mutable fields but promises not to take them into account when computing hashCode() and equals(), then the class is of course unsafe when it comes to multi-threading, but it can still be considered as immutable for the purpose of using it as a key in a map. So, all these cases can be handled in one of two ways:
Manually adding classes (and interfaces) to your immutability detector. If you know that a certain class is effectively immutable despite the fact that the immutability test for it fails, you can manually add an entry to your detector which associates it with Immutable. This way, the detector will never attempt to check whether it is immutable, it will always just say 'yes, it is.'
Introducing an #ImmutabilityOverride annotation. Your immutability detector can check for the presence of this annotation on a field, and if present, it may treat the field as immutable despite the fact that the field may be non-final or its type may be mutable. The detector may also check for the presence of this annotation on the class, thus treating the class as immutable without even bothering to check its fields.
I hope this helps future generations.
I doubt you can do this with unit tests. The best way would be to be careful during writing the class or looking into the code. Precisely because of the problem that methods on the object can mutate its state which you might not see from the outside. Just because it's discouraged doesn't mean it doesn't happen :-)
Pretty sure it is impossible. Consider this function:
public void doSomething() {
if (System.currentTimeMillis() % 100000 == 0) {
this.innerMember.changeState();
}
}
First, you won't be able to detect it by running every class function, as this function changes the state of object precisely only once in 100 seconds.
Second, you won't be able to detect it by parsing code, as you do not know if changeState() function changes the state of innerMember or not.
This thread can help How do I identify immutable objects in Java. Take a look at the second popular answer, it might be possible to check for any immutability problems with FindBugs. If you run it on every commit then you can call it a unit test :)
EDIT
It seems that FindBugs only check for final, that's not much. You could implement your own rule according to you patterns and classes which you use in the code.
I'd like to be able to specify that an object's member variables are immutable once the object has been "initialized", which to me means after it has been injected with any dependencies, and has performed any other initialization operations that it can only perform after DI.
Are there languages that satisfy my interest - that formalize DI, initialization, and support immutability in this fashion? Maybe it's dumb to make them a part of a language; maybe not. I'm not sure.
Today I program in Java, but I can't use "final" nearly as much as I'd like, because those phases happen after the constructor has finished execution. Any advice on how to get what I want with Java? I guess I could have my objects implement a base class so that those phases happen before the constructor finishes, or use aspects to do the same.
Thoughts?
There are two main ways of producing immutable objects:
use the builder/factory pattern - the builder may be mutable, but the objects it creates are immutable, usually implemented with final fields. You can also combine the two, so the object itself is used to build new instances, usually via "mutator" methods that change state on a separate, new instance. Spring's FactoryBean is an example of this.
create a MutableObject subclass, which maintains a flag for mutable state. All your mutators check the mutable state before making any changes - if the object has been set to immutable, then the check throws an exception, otherwise the change goes ahead.
The first approach is quite Spring-centric, since it requires implmentation of a spring-specific interface. You can create factory beans that are regular beans, via factory-method/factory-bean attributes on a bean, which removes the spring dependency from your code.
Using the second approach is particularly useful with spring. You can instruct spring to call a method after bean initialization, e.g. seal() which seals the object - makes it immutable. Alternatively, you can implement a small BeanFactoryPostProcessor to do this automatically without having to remember to set the init-method="seal". on each immutable bean.
I guess it depends on what you want out of the immutability. If you want the guaranteed thread safety (where everything must be declared final, including the dependencies) then I think factory, builder or constructor injection are your only options.
If however you just want immutability of state, then declaring the state variables final should be enough. Even the immutable String class has a mutable field in its implementation (a cache of the hashcode value). As long as your code otherwise ensures that an instance is not available without injection, all should be well.
In Java, you can use a builder to initialize an immutable object in its constructor, so you'd shy away from setters.
If you use Scala, though, immutability is the default.
In Java, if you're using mutator methods to do your setting anyhow, it's pretty cheap (though also pretty ugly in my eyes) to add logic to prevent alterations once the object is initialized.
public void setMyProperty(String newValue) {
checkInitialized();
myProperty = newValue;
}
public void checkInitialized() {
if ( initialized ) {
throw new IllegalStateException("Setter called after initialization");
}
}
At best though this is giving a dynamic check. It doesn't give you any static feedback over what you would have already had.
To specify that a class is immutable, you can use the #Immutable annotation.
You can see the Javadoc here.
This works well with the Findbugs plugin in Eclipse.
#Alexander:
As I understand him, he asked how to specify that a class is immutable. Not how to write an immutable class. This annotation can give you tool support to verify that you don't have a bug in your class that you claims are immutable.
A snippet from the Javadoc:
Of necessity this means that all
public fields are final, and that all
public final reference fields refer to
other immutable objects