This question already has answers here:
Why do we need immutable class?
(20 answers)
Closed 8 years ago.
I found an article with an interesting piece of code:
public class Employee {
private String firstName;
private String lastName;
//private default constructor
private Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public static Employee valueOf (String firstName, String lastName) {
return new Employee(firstName, lastName);
}
}
I am really curious in understanding the advantage of creating this kind of classes.
I understand that here that an object of this class would be immutable, because there is no way of changing its variable values once initialized. I never did something like this before, and i dont really understand the advantage of it.
Why is it a good practice?
Could you name a situation where this approach can be used?
What about constants or read only variables? Is not that very similar?
In the article says, that this is not good for the performance of the application. But why?
The example you have mentioned is of an Immutable Objects. Its widely used concepts in programming languages.
Quoting from the link above. The advantages are
are simple to construct, test, and use
are automatically thread-safe and have no synchronization issues
do not need a copy constructor
do not need an implementation of clone
allow hashCode to use lazy initialization, and to cache its return value
do not need to be copied defensively when used as a field
make good Map keys and Set elements (these objects must not change state while in the collection)
have their class invariant established once upon construction, and it never needs to be checked again
always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object - throws an exception, it's never left in an undesirable or indeterminate state
Immutable classes are:
thread-safe by default (concurrent write never occurs)
cachable
You can read a lot about them in the conext of the language Java in Effective Java.
-Why is it a good practice?
Because you can pass the class around and be sure it will never be modified by a "rogue" code. Same for Java Strings, they're immutable.
-Could you name a situation where this approach can be used?
It's very useful on big projects where many teams work together, or when designing a framework or an API. In these situations, since you're not responsible of parts of the code, you can never trust that an object you pass to other parts of the code won't be altered. Use immutability if you need to ensure the object won't be modified.
-What about constants or read only variables? Is not that very similar?
Not in Java because we have neither const nor read-only. All we have is the final keyword that ensures an object reference won't be modified beyond first assignment. But the underlying object can still be modified even if the reference can not. Immutable classes ensure an object state won't be altered after creation.
-In the article says, that this is not good for the performance of the application. But why?
Because every time you need to modify the object, you need to create new instances. Same for Strings, you can't do myString.append("42"), you need to do myString = myString+"42", which creates a new String object.
The main advantage of immutable classes is thread-safety. Most problems with threading come from having shared, mutable state. By making objects immutable, it is far easier to reason about them especially in multi-threaded environments.
The article says "creating immutable objects can hit performance of an app." I'm not sure why it says this. It's totally wrong. There is nothing inherent about immutable objects that could affect the application's performance.
If you are using hashTables, having immutable objects is good because you dont need to recalculate the hashCode when the state of the object changes(as they are unchangeable).
The article says:
To make a class immutable you can define its all constructors private and then create a public static method to initialize and object and return it.
Actually, that is wrong. These two concepts aren't really related.
E.g. you could declare the constructor of your Employee class public and it would still be immutable.
Or you could pass a mutable Object as a parameter to the factory method or declare a mutator method
-> Employee would be mutable although you're using a factory method and a private constructor.
In your given example he is making constructor as private, and thus controlling the object creation from outside directly.
Meaning : Since constructor is private, you can't do
Employee e = new Employee("steve","jobs");
from outside of this class.
By doing so, the programmer of this class, is taking object creation for this class into his control.
This is very beneficial, when you are writing very huge Server side class, for which creating an object may take lot of memory due to its size. Now how do you protect from your clients, of not creating more objects for your class?
Answer for above question is simple, by making your constructor private and you yourself creating objects for your class when ever you want in static method.
Note: Static methods can be accessed directly by using class name.
Note: This kind of design patterns will be heavily used in singleton design patterns, which requires only one object for a given class.
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.
This question already has answers here:
Constructors vs Factory Methods [closed]
(10 answers)
When to use a Constructor and when to use getInstance() method (static factory methods)?
(6 answers)
Closed 9 years ago.
Well, i have a very conceptual question. A lot of things look like fabrics, where i'm not sure where the great benefit is.
As example
public class MyObject {
public MyObject() {
}
public static MyObject create() {
return new MyObject();
}
public void doSomething(){
// some code...
};
}
The only benefits from my point of view is a bid less to code. In my opinion, no impact on performance happens. Are there other benefits?
MyObject myobject = new MyObject();
or
MyObjecct myobject = MyObject.create();
Thanks
You are correct in that there is no significant performance difference; and the reasons for using this form are primarily about readability of the code.
In general if you use the static create function you would declare the constructor private thus ensuring your users can ONLY create objects with the static function
In general I don't think the static create adds much to code, ad for ordinary everyday objects a new is probably clearer and more direct.
However there are some cases that I think the static constructor is useful:
For construction of large complicated objects, especially objects involving a lot of complexity in initialisation - often a simple constructor misleads library users into assuming the construction task is fast and easy.
If you have multiple constructors with ambiguous parameters you can use the static function name to make it more readable, for example you might have createFromFile(String FileName) and createFromJSONEncoding(String Data)
You want to control if a new object is ACTUALLY created - for example if this is a read-only resource you might be keeping a buffer of the resources already open and if the library user requests the same resource twice you can simply give them an already cached copy (as opposed to making a new duplicate copy)
Joshua Bloch addresses this concern in Effective Java, Chapter 2, Item 1: Consider static factory methods instead of constructors; here are a few highlights:
"One advantage of static factory methods is that, unlike constructors, they
have names." -- you can't have two different constructors that take an int argument, but you can have two static factory methods called createWithAge(int age) and createWithHeight(int height)
"A second advantage of static factory methods is that, unlike constructors,
they are not required to create a new object each time they’re invoked."
"A third advantage of static factory methods is that, unlike constructors,
they can return an object of any subtype of their return type."
As you see, the concern is hardly related to performance (except for reusing cached instances), but mainly to object oriented design.
DISCLAIMER: Oops, I just saw the same answer (far better explained) already being posted for a different question: https://stackoverflow.com/a/3169644/262683. My bad...
There is no answer to this question.
The fact is that both patterns are legitimate ways to construct objects that are applicable to particular situations.
Static factory methods are important in situations where instance control is very important, such as in systems that maintain object caches or pools.
The new operator is apt for its simplicity and is rather important for classes that are designed for inheritance.
You are asking what is the best practice. The answer is that the best practice depends on your goals and, as always for questions of this sort, the best practice is that which makes smart use of available tools to reach a scalable and maintainable solution.
I suggest that this question be closed.
The case I see where you might need to use create:
You have to control creation of every instance of your class. For example, you count number of objects created or link them somehow and if number of instances reached your desired maximum throw exception.
Also factory pattern might be interesting to read about.
If you're not sure, just create via new
And if you choose to go with create you'd probably want to make your constructor private
It is a (simplistic) Factory Pattern. Please check the applicability section of the Wikipedia entry to see where it is used.
Now when you don't wan't any other class to create your class' object then you make you class constructor private:
private MyObject()
now any class wanting to create your class object will have to do this :
MyObjecct myobject = MyObject.create();
Because now doing this inside some other class MyObject myobject = new MyObject(); will cause compiler error.
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.
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.
Today while I was reading some documentation regarding the BigDecimal class,
I've stumbled upon an fundamental property, the BigDecimal class is Immutable.
How could I explain to my grandmother the immutability concept ?
What are the pro and cons of the immutability of a class ?
Can an extended class become mutable ?
Considering that I want to extend the BigDecimal with my class:
`MyBigDecimal extends BigDecimal`
Does the extending violate the basic Object Oriented design principles ?
How could I explain to my grandmother the immutability concept ?
Check this question: What is meant by immutable
Or from Effective Java:
An immutable class is a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.
What are the pro and cons of the immutability of a class ?
Pros:
it's easier to reason about the state of the object, because there is only one, the state that was built upon initialisation
corollary: immutable objects are easier to use in concurrent programming, where state is everything
Cons:
when you want to change a property of the object, you need to create a new one = expensive
construction can be more complicated (cf builder pattern)
Can an extended class become mutable ?
Yes - which is why immutable class should be made final (or alternatively, make all constructors private and provide factories to create new objects).
BigDecimal is a good example of what should not be done when creating an immutable class (it can be extended which can cause issues as you mentioned in your question).
The BigDecimal is a value class. It represents a value from the "real world". Let's take the whole numbers for example. A 42 has always the value 42. It's state cannot be changed. If I want to have the 43 it is not the changed value of 42 but the value of 43. This abstract concept of values is transfered in the object oriented world by using immutable classes. If you want to add a number to your existing one it is not changed but a new immutable object containing the result is created.
An Immutable class whose instances never change. The state of the object is defined at construction time and never changes after.
To be properly immutable, the class doesn't provide any way (other than reflection) to change its state: no setter method, no method that changes its internal state, no method that allows accessing to a mutable field it holds. It should also be final (as BigDecimal should be), to prevent any other class to extend it and thus make it mutable by adding mutable fields.
The advantages are many:
The class is easy to understand
Instances are inherently thread-safe
Instances can be cached without needing to return copies from the cache
Instances can be used as keys in a Map without fear of being changed after
It doesn't violate OO principles: to the contrary, the state is completely encapsulated in the object.
Note: some immutable objects change their state internally (lazy initialization of some fields, for example) without affecting the externally-visible state of the object. If done properly, it doesn't change the thread-safety of immutable objects. If done incorrectly, it can make them non-thread-safe.
immutability of a class means if object is created you can not change its contents.
Consider e.g.
String str = "Hello"; // you can not change content Hello to any other string
Pros and cons of immutability of a class - Pros. / Cons. of Immutability vs. Mutability
Can an extended class become mutable ?
Yes you can make it.
MyBigDecimal extends BigDecimal
You can do it BigDecimal is not final.