I want to have immutable Java objects like this (strongly simplified):
class Immutable {
protected String name;
public Immutable(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
In some cases the object should not only be readable but mutable, so I could add mutability through inheritance:
public class Mutable extends Immutable {
public Mutable(String name) {
super(name);
}
public void setName(String name) {
super.name = name;
}
}
While this is technically fine, I wonder if it conforms with OOP and inheritance that mutable is also of type immutable. I want to avoid the OOP crime to throw UnsupportedOperationException for immutable object, like the Java collections API does.
What do you think? Any other ideas?
Avoid calling the parent "Immutable" because it becomes a lie in the child class - if you do want to make a class immutable, it should be final too in order to prevent exactly this problem.
Joda Time uses "ReadableXXX" to give the idea that "this class only provides read access; other subclasses may be mutable". I'm not sure whether I like that idea, but I can't say I've seen many alternatives.
Basically the problem is with expressing a negative - Immutable describes what you can't do (mutate it) and that can't be sensibly enforced in subclasses. (Even if the fields within Immutable were final, it wouldn't stop a subclass having its own mutable fields.)
Your subclass is bad because it violates the Liskov substitution principle. Don't do it.
I would suggest that you should have an inheritable base "ReadableFoo" class, a derived sealed ImmutableFoo class, and other derived MutableFoo classes. Code which doesn't care whether a Foo is mutable or not can accept a ReadableFoo. Code that wants a Foo that is guaranteed not to change can accept an ImmutableFoo. Code which can need to change a Foo can accept a MutableFoo.
Note that the constructors for both ImmutableFoo and MutableFoo should typically accept a ReadableFoo. That way, any Foo will be convertible to a mutable or immutable version.
Immutable classes should be final precisely to avoid mutable sub-types.
Allowing a sub-type of an immutable class to break the immutable contract makes it rather pointless to have the class be immutable in the first place. It may be legal in the sense that Java allows you to do it (immutability is not enforced in the language) but such a class isn't truly immutable as long as it can be sub-classed.
This is why String is final.
I find your code rather curious.
To implement such an Immutable behaviour, I would rather has relied upon an Immutable interface, providing only the getter method, whiile the object contains both. This way, operations relying on the immutable objects would have called the interface, while others would have called the object.
And, if you really don't want your immutable objects to be casted as mutable ones, you can then use proxies, and all the enterprise tools (aspects, and so on). But usually, relying upon other developpers' goodwill is a sweet way to make them responsible of their mistakes (like casting the immutable in mutable).
Related
So, I read somewhere that there are 3 requirements for a class to be immutable in Java.
All data fields must be private.
There can't be any mutator methods for data fields.
No accessor methods can return a reference to a data field that is mutable.
But I don't agree with #2 because even if a class has mutator methods, it can be immutable as long as those mutator methods are private. Am I right or wrong? Can you explain in detail?
There are different possible definitions of immutability.
The definition you mention does not allow any state change of an object. In particular, after it has been created, it cannot modify its own state.
However, sometimes, an immutable object is defined as an object whose state cannot be observed to change. When immutability is defined like this, the state of an immutable object is allowed to change if this state change cannot be observed from the outside. For example results of expensive calculations could be cached, or some internal statistic information could be recorded, or something like that.
One advantage of immutable objects which is often stated is that they are automatically thread-safe. It is important to note that this advantage only holds when you define immutability in the strong way (the first option above). If an object which only changes its non-observable state is accessed concurrently by two threads, it could in principle still produce erroneous results, so the programmer must take additional care that the object is thread-safe.
EDIT
But I don't agree with #2 because even if a class has mutator methods,
it can be immutable as long as those mutator methods are private
Because it is a private mutator does not guarantee that it does not change state, but as long as it does not change state what it it supposed to remain intact we can take as immutable. because immutability is remaining intact once set.
Immutable only has a getter. There's no way to change the value of its fields once it's set.
Lets take String class, it is immutable
Once a String object is created, it is not allowed to change. It cannot be made larger or smaller, and you cannot change one of the characters inside it. You can think of a string as a storage box you have perfectly full and whose sides can't bulge. There's no way to add objects, nor can you replace objects without disturbing the entire arrangement.
so immutablity of a class should be like that.
There are other ways to break your immutable object. For instance, reflection API.
I believe if you decided to make it immutable, would you mind to erase the private setter method. It just doesn't make sense to keep it there.
Yes, there can't be any mutator methods for data fields.
The reason is that setting the method private only effects the scope of the method. If you want a truly immutable variable then you must set variable final as well. This way your variable cannot be mutated.
Directly taken from Wikipedia:
In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created.
So definitely if you have a class with a mutator method that changes state of the object (intended as class instance) then that class is not immutable. To consider it as immutable every method must not change its state, but produce another object of the same class, with the modification applied.
Actually what is the point of private mutators?
Immutable means that the object's state can't change in any way after it's creation. Doesn't matter if it's via direct access to the fields, through mutators or some other "random" method that changes the state. None of this is allowed for a class to be immutable.
Immutable doesn't mean: another class can't change the state of this Object, it means: The state of this Object can never change.
Consider this code:
public Person {
private String name;
public Person(String name) {
this.name = name;
}
private void setName(String name) {
this.name = name;
}
public boolean hasName(String name) {
boolean result = this.name.equals(name);
this.name = name;
return result;
}
}
This can't be considered an Immutable class, since even if it doesn't seem so to the class that calls hasName(String name), the state of the Object changes. Seeing that normally, an immutable class usually has it's members declared as final, this would not even compile.
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 am currently enrolled in a CS2 course (data structures) where Java is the language used and I am interested in comparing and contrasting object instantiation using the traditional constructor method v.s. a factory method. Does one represent a greater degree of computing elegance than the other? Would a factory method handle parameters in a manner similar to a parameterized constructor? E.g:
public class Tester
{
private String name;
private int age;
// Parameterized constructor
public Tester(String myName, int myAge)
{
this.name = myName;
this.age = myAge;
}
}
Essentially, I'm very curious on how one would write an equivalent factory method and what the potential benefits would be of doing so.
Thanks,
~Caitlin
Factory methods are nice as they can return a reference to an object that isn't necessarily an instance of that class. It can return that class, a subtype, or even null, and generally carry themselves on any way they want that a method can. You can thus move logic of selecting types into your own code. You can return an existing instance where appropriate, saving heap space and such.
Another basic pseudoexample is Integer.forValue() that can intern an integer, so identical immutable objects don't get recreated for no reason. Also see Executors.newXxxThreadPool().
A basic example:
public class Tester
{
private String name;
private int age;
// Parameterized constructor
private Tester(String myName, int myAge)
{
this.name = myName;
this.age = myAge;
}
public static Tester getTester(String mn, int ag){
if(age>0){return new Tester(mn, ag);}
else if(age>80){return new OldPersonThatExtendsTester(mn, ag);}
//we'd need a public or otherwise accessible constructor above. It's a subtype!
else {return null;} //yes, this is possible
}
}
According to the well-reasoned observations in Effective Java, the main advantages to static factory methods are as follows:
You can name them, unlike constructors which must always be named after the class. This makes code more readable and can avoid ugly situations where overloaded constructors might be impossible due to the types of arguments being the same, etc. In such a case, you could easily supply two factory methods with different names that indicate the difference.
A static factory method is not required to actually instaniate anything unlike a constructor which must create a new instance. Static factory methods are therefore essential for classes that are instance-controlled (eg. singleton classes).
Unlike constructors, a static factory method can return any object at all as long as the returned object matches or is a subclass of the return type. This enables interface-based type systems. The Enum framework of Java 1.5 makes use of this: the EnumSet class has no public constructors, only static factories. The actual object that is returned by the static factories varies depending on the size of the enum.
The main disadvantage of static factories is that they cannot be the basis of a class designed for inheritance. A class that provides only private constructors cannot be subclassed. A minor disadvantage of static factory methods is that they cannot be distinguished from other static methods, and so in order for them to be recognizable to the reader they usually follow naming patterns (they can be annotated if such a one is designed as a marker annotation for static factory methods).
A factory is useful in specific situations:
Where one of several different subclasses of the object might be returned, based on parameters.
Where there is some need to "guard" the creation of objects, perhaps for security, perhaps for some sort of synchronization.
Where created objects need to be "enrolled" somehow after creation, and doing so in the constructor is not feasible.
Where one does not even want to load the (actual) class (and it's tree of referenced classes) unless an instance must be created.
Where some reason such as the above is not present, there is no benefit to factory methods, and they simply obscure the logic.
There is no real restriction on what a factory can do, given that it can (if things are set up properly) access package level constructors and interfaces that are not accessible to the hoi polloi.
Added: To address the "inheritance" issue --
Let's say we have the classical Vehicle example, with Car and Truck subclasses. If you simply have CarFactory and TruckFactory then that increases the complexity of the code for no good reason (unless there are other compelling reasons for using factories).
But you can have a VehicleFactory and have it "decide", based on input or external factors, to create a Car or a Truck. This is a fairly common pattern.
However, if you were to (for some reason) have a VehicleFactory that only created Vehicle objects (not Cars or Trucks), and if use of the factory were mandatory (you couldn't access Vehicle's constructors), that would make it essentially impossible to subclass Vehicle. When you use a factory you make it very difficult (at the least) for someone else to add new subclasses.
Could you please clarify that why final keyword is required before class when we are making it an immutable one.
I mean, if we declare all of it's attributes as private and final, then also it is an immutable class, isn't it?
Sorry if the question seems easy, but i am truly confused about it. Help me out.
Editted:
I know that a class declared final can't be subclassed.. But if each attribute is private and final then what difference does that make?
As stacker says, final makes sure the class isn't subclassed. That's important so that any code which is relying on its immutability can do so safely.
For example, immutable types (where each field is also of an immutable type) can be freely used between threads without worrying about data races etc. Now consider:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
That looks like you can share Person instances freely across threads with no problem. But what about when the object you're sharing is actually a mutable subclass:
public class Employee extends Person {
private String company;
public Employee(String name, String company) {
super(name);
this.company = company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCompany() {
return company;
}
}
Now instances of Employee aren't safe to share between threads, because they're not immutable. But the code doing the sharing may only know about them as instances of Person... leading them into a false sense of security.
The same goes for caching - it should be safe to cache and reuse immutable types, right? Well, it is safe to cache instances which are genuinely of an immutable type - but if you're dealing with a type which itself doesn't allow mutation, but does allow subclasses, it's suddenly not safe any more.
Think about java.lang.Object. It doesn't have any mutable fields, but it's clearly a bad idea to treat every Object reference as if it's a reference to an immutable type. Basically it depends on whether you think about immutability as a property of the type or of objects. A truly immutable type declares "any time you see a reference of this type, you can treat it as immutable" - whereas a type which allows arbitrary subclassing can't make that claim.
As an aside, there's a half-way house: if you can limit the subclassing to only "trusted" places, you can ensure that everything's immutable, but still allow that subclassing. The access in Java makes that tricky, but in C# for example you could have a public class which only allowed subclassing within the same assembly - giving a public API which is nice and strong in terms of immutability, while still allowing for the benefits of polymorphism.
A class that is declared final cannot be subclassed. See also http://docs.oracle.com/javase/tutorial/java/IandI/final.html
The different semantics of all uses of the final keyword are described in the The Java Language Specification
4.12.4 final Variables Page 80
8.1.1.2 final Classes Page 184
8.3.1.2 final Fields Page 209
8.4.3.3 final Methods Page 223
You don't strictly need final to make an immutable class. i.e. you can make an immutable class without it being final.
However, if you don't make it final, then it is possible for someone to extend a class and create a subclass that is mutable (either by adding new mutable fields, or overriding methods in a way that enables you to mutate protected fields of the original immutable class). This is a potential problem - it violates the Liskov Substitution Principle, in the sense that you would expect the property of immutablity to be preserved by all subtypes.
Hence, it is usually good practice to make immutable classes final to avoid this risk.
'final' as the keyword's name suggest means that the attribute to which final keyword is attached can't be changed(in terms of value) in other words it behaves like a constant.
As per your question if all members of the class is made private and final but the class is not made final then the same class can be inherited but the super class member are immutable as final keyword is attached to them.
An immutable object is an object which state is guaranteed to stay identical over its entire lifetime. While it is perfectly possible to implement immutability without final, its use makes that purpose explicit, to the human (the software developer) and the machine (the compiler).
Immutable objects carry some very desirable characteristics:
they are simple to understand and easy to use
they are inherently thread-safe: they require no synchronization
they make great building blocks for other objects
Clearly final is going to help us define immutable objects. First in labelling our object as immutable, which makes it simple to use and understand by other programmers. Second in guaranteeing that the object's state never changes, which enable the thread-safe property: thread concurrency issues are relevant when one thread can change data while another thread is reading the same data. Because an immutable object never changes its data, synchronizing access to it is not needed.
Create an immutable class by meeting all of the following conditions:
Declare all fields private final.
Set all fields in the constructor.
Don't provide any methods that modify the state of the object; provide only getter methods (no setters).
Declare the class final, so that no methods may be overridden.
Ensure exclusive access to any mutable components, e.g. by returning copies.
A class declared final cannot be sub classed. Other classes cannot extend final class. It provides some benefit to security and thread safety.
If all public and protected methods are final and none of them allows modifying private fields, and all public and protected fields are both final and immutable, then I guess it could be said class is semi-immutable, or sort of constant.
But things break down when you create a subclass and need to override equals and hashcode. And can not because you made them final... So the whole thing is broken, so just make the whole class final to prevent programmer from being a fool by accident.
As an alternative to doing this kind of bastardized version immutability, you have several options.
If you want to attach extra data to immutable instance, use Map. Like if you wanted to add age to name, you would not do class NameAge extends String... :-)
If you want to add methods, create a class of static utility functions. That is a bit klunky, but it is the current Java way, Apache commons for example is full of such classes.
If you want to add extra methods and data, create a wrapper class with delegate methods to methods of the immutable class. Anybody needing to use the extra methods needs to be aware of them anyway, and there is not much practical difference in casting to derived non-immutable class or doing something like new MyWrapper(myImmutableObj) for many use cases.
When you really have to have reference to original imutable object (like storing it in existing class you can not change), but need the extra data somewhere, you need to use the Map approach to keep the extra data around, or something like that.
If an immutable class Foo is sealed ("final"), then anyone who receives a reference to a Foo may be assured that if Foo was implemented correctly, the referenced instance will in fact be immutable. If an immutable class is not sealed, then someone who receives a reference to a Foo may be assured that if the actual class of of the referenced object (which may be Foo or some derivative type implemented by some arbitrary unknown person) was implemented correctly, the instance will be immutable. Leaving Foo unsealed means that anyone who relies upon Foo to be immutable will have to trust that everyone who writes a class that derives from Foo will implement it correctly. If one wants to be certain that every reference to a Foo will in fact target an immutable instance without having to rely upon the authors of derivative classes to abide by the contract, making Foo final can aid in such assurance.
On the other hand, the possibility that a class might derive from Foo but violate its immutability isn't terribly different from the possibility that a class which derives from any other class might violate the contracts of its parent class. Any code which accepts a reference of any type which can be subclasssed by outside code might be given an instance of a subclass which violates its parent's contract.
The fundamental question when deciding whether an immutable class should be sealed is the same as for any other class: whether the benefits of leaving the type unsealed outweigh any dangers that would be posed by doing so. In some cases, it may make sense to have an extensible immutable class, or even an abstract class or interface whose concrete implementations are all contractually obligated to be immutable; for example, a drawing package might have an ImmutableShape class with some concrete fields, properties, and methods to define 2D transformations, but an abstract Draw method, allowing for the definition of derivative types ImmutablePolygon, ImmutableTextObject, ImmutableBezierCurve, etc. If someone implements an ImmutableGradientFilledEllipse class but fails to have that type make its own copy of a mutable GradientColorSelector, the colors of gradient-filled polygons might change unexpectedly, but that would be a fault of the ImmutableGradientFilledEllipse class, and not the consuming code. Despite the possibility of a broken implementation failing to uphold the "immutability" contract, an extensible ImmutableShape class would be much more versatile than a sealed one.
I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?
The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...
Am I missing something?
All fields in interface are public static final, i.e. they are constants.
It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.
First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.
In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.
Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.
But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.
Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.
(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).
What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?
interface IdFinder {
Serializable UNSAVED = new Serializable() {};
/** #returns the given entity's persistent identity,
or {#link UNSAVED} if it hasn't been saved yet,
or null if o is a value object that hasn't a
persistent identity of its own.
*/
Serializable getId(Object o);
}
Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:
public class Constants {
private Constants() { }
public static final int ZERO = 0;
public static final int SOME_COMPLEX_NUM = 2124132L;
...
}
You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)