What is an immutable object
An object is called immutable if its state cannot be modified by anyone in any way after its construction, here object's state means the fields or the variables it is holding.An immutable object does not expose its state to the outer world and neither provides any behaviour to modify its state. All wrapper classes i.e
Integer
, Float
, Long
are immutable in nature and other examples of immutable classes are String
, java.util.UUID
, java.net.URL
.Advantages of immutable objects
In Why String is Immutable and Final in Java, I have discussed how just by being immutable in nature, String gains lots of advantages including- Thread Safety,
- Hash-code caching,
- Object pool,
- Security.
How to create a class for an immutable object
To create an immutable object we need to define our class in a way that it restricts every one (including itself) from changing the state of the object after its construction, and in order to do so we need to- Mark your class final,
- Mark all the fields private,
- Mark all fields final as well,
- Provide an argument constructor with all initialization logic,
- Initialize all mutable fields by deep copying,
- Do not provide setters for your fields,
- Return a deep copy of mutable fields from the getters.
Let's look at all these rules and the reasons to follow them
1. Why mark our class final
We should declare our class final to forbids its extension so no one can extend our class and destroy its immutability. If it is not final then in future someone might extend it and modify the behaviour to change the state.2. Why mark all the fields private
We should mark all the fields private so no one can access them outside of the class.3. Why mark all fields final as well
Mark all the fields final so even we will not be able to change the fields outside of the constructor.4. Why provide an argument constructor with all initialization logic
A constructor is a place to write our object initialization logic because constructor gets called whenever we create an object.So when we want to set our object's state during object creation only, we need to set it in the constructor and that's why we need to have an argument constructor in case of an immutable class.
As discussed in 5 different ways to create objects and creating objects through reflection, serialization and cloning also create new objects but both of them does not include a constructor call. But we do not need to worry about it because in both ways object will be constructed from an already present object which will be already immutable in nature.
5. Why initialize all mutable fields by deep copying
If our immutable object holds a reference to other immutable objects i.e.String, Integer
we do not need to worry because we know they will not allow any change in their state.But if our object holds references to some mutable objects and those mutable objects are also getting referred from somewhere else, in that case, our object's immutability is in danger.
In our example, our
ImmutableEmployee
class holds a reference to Date
class which is mutable in nature. In below lines of code we are creating a variable dob
which is holding a Date object and then we are passing it to ImmutableEmployee's
constructor and creating an object which is being referred from employee
.Date dob = new Date();
ImmutableEmployee employee = new ImmutableEmployee(1, "Naresh", dob);
When we
SysOut
employee object we will getImmutableEmployee{id=1, name='Naresh', dob=Sun Jan 10 00:12:00 IST 1993}
Now if we do not initialize
dob
fields by deep copying then both dob
and employee.dob
will point to a single object and if we change anything in dob,
employee.dob
will also reflect that change which means employee
object will become mutable.But by deep copying
dob
field both employee.dob
and dob
will point to two different objects and we will not face this problem, as you can see output of below codedob.setMonth(1);
System.out.println(dob); // Prints - Wed Feb 10 00:12:00 IST 1993
System.out.println(employee.getDob()); // Prints - Sun Jan 10 00:12:00 IST 1993
System.out.println(employee); // Prints - ImmutableEmployee{id=1, name='Naresh', dob=Sun Jan 10 00:12:00 IST 1993}
In our example, I have used the copy constructor
this.dob = new Date(dob.getTime());
to copy our objects because there are some basic problems with Java cloning and we can not sure of either it is a deep copy or shallow copy without seeing cloning code of that class.You can read more about cloning, cloning types and why copy constructors are better than on more detailed articles such as Java Cloning And Types Of Cloning (Shallow and Deep), Java Cloning - Copy Constructor Versus Cloning and Java Cloning - Even Copy Constructors Are Not Sufficient.
6. Why should not provide setters for your fields
Well, providing setters will allow us to modify the state of the object which we do not want.7. Why return a deep copy of mutable fields instead of returning objects from the getters.
If we return all mutable fields directly, we will face the same scenario as discussed in point 5 and after executing below code bothemployee.dob
and temp
will point to the same object, now if we make any change in temp
, employee.dob
will also change which again means employee
will not remain immutable.So instead of returning mutable fields, we should return their deep copy and as we have done that, we can see in below code
employee
remains same and immutable at the end.Date temp = employee.getDob();
temp.setMonth(2);
System.out.println(temp); // Prints - Wed Mar 10 00:12:00 IST 1993
System.out.println(employee.getDob()); // Prints - Sun Jan 10 00:12:00 IST 1993
System.out.println(employee); // Prints - ImmutableEmployee{id=1, name='Naresh', dob=Sun Jan 10 00:12:00 IST 1993}
In the end, I wanted to say that all immutable objects in Java are effective immutable not completely immutable because we can modify them using reflection.
Below is the complete source code to create an immutable class which you can also find on this Github Repository and please feel free to provide your valuable feedback.
// 1. Declare your class as final, So other classes can't extend it and break its immutability
final class ImmutableEmployee {
// 2. Make all your fields private they can't be accessed outside your class
// 3. Mark them as final so no one can modify them anywhere else apart from the constructor, if you do not have any specific requirement to not do so
private final int id;
private final String name;
private final Date dob;
// 4. Create an constructor with argument so you can assign instantiate your object with a proper state
public ImmutableEmployee(int id, String name, Date dob) {
this.id = id;
this.name = name;
// 5. Initialise all your fields by deeply copying them if they are not immutable in nature
this.dob = new Date(dob.getTime());
}
// 6. Do not provide setters for your fields, or define them private if you have some requirement
public int getId() {
return id;
}
public String getName() {
return name;
}
// 7. Instead of returning objects from the getters return deep copy them if your objects are not immutable
public Date getDob() {
return new Date(dob.getTime());
}
@Override
public String toString() {
return "ImmutableEmployee{" +
"id=" + id +
", name='" + name + '\'' +
", dob=" + dob +
'}';
}
}
public class ImmutableClassExample {
public static void main(String[] args) throws ParseException {
Date dob = new SimpleDateFormat("dd-mm-yyyy").parse("10-12-1993");
ImmutableEmployee employee = new ImmutableEmployee(1, "Naresh", dob);
System.out.println(employee); // Prints - ImmutableEmployee{id=1, name='Naresh', dob=Sun Jan 10 00:12:00 IST 1993}
dob.setMonth(1);
System.out.println(dob); // Prints - Wed Feb 10 00:12:00 IST 1993
Date temp = employee.getDob();
temp.setMonth(2);
System.out.println(temp); // Prints - Wed Mar 10 00:12:00 IST 1993
System.out.println(employee.getDob()); // Prints - Sun Jan 10 00:12:00 IST 1993
System.out.println(employee); // Prints - ImmutableEmployee{id=1, name='Naresh', dob=Sun Jan 10 00:12:00 IST 1993}
}
}
package TrafficSystem;
ReplyDeleteimport java.util.ArrayList;
import java.util.Iterator;
interface Observable
{
public void registerObserver(Observer o);
public void unregisterObserver(Observer o);
public void notifyObservers();
}
class currentTraffic implements Observable
{
String current_condition, vip_tc, emergency, violance;
ArrayList observerList;
public currentTraffic() {
observerList = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
observerList.add(o);
}
@Override
public void unregisterObserver(Observer o) {
observerList.remove(observerList.indexOf(o));
}
@Override
public void notifyObservers() {
for (Iterator it = observerList.iterator(); it.hasNext();)
{
Observer o = it.next();
o.update(current_condition, vip_tc, emergency, violance);
}
}
private String getCC()
{
return "Heavy Traffic";
}
private String getVTC()
{
return "Yes";
}
private String getE()
{
return "Ambulance";
}
private String getV()
{
return "Attack";
}
public void dataChanged()
{
current_condition = getCC();
vip_tc = getVTC();
emergency = getE();
violance = getV();
notifyObservers();
}
}
interface Observer
{
public void update(String current_condition, String vip_tc, String emergency, String violance);
}
class currentTrafficDisplay implements Observer
{
String current_condition, vip_tc, violance;
@Override
public void update(String current_condition, String vip_tc, String emergency, String violance) {
this.current_condition = current_condition;
this.vip_tc = vip_tc;
this.violance = violance;
display();
}
public void display()
{
System.out.println("Now there is "+current_condition+".");
System.out.println("VIP Traffic Condition: "+vip_tc+".");
}
}
class emergencyDisplay implements Observer
{
String emergency;
@Override
public void update(String current_condition, String vip_tc, String emergency, String violance) {
this.emergency = emergency;
display();
}
public void display()
{
System.out.println("The main emergeny of "+emergency+" is ON.");
}
}
class signalDisplay implements Observer
{
String current_condition, vip_tc, violance;
@Override
public void update(String current_condition, String vip_tc, String emergency, String violance) {
this.current_condition = current_condition;
this.vip_tc = vip_tc;
this.violance = violance;
display();
}
public void display()////////////////////////////
{
System.out.println("The display of the signal is Reg light.");
}
}
public class TrafficSystem {
public static void main(String[] args) {
currentTraffic ct = new currentTraffic();
currentTrafficDisplay ctd = new currentTrafficDisplay();
emergencyDisplay ed = new emergencyDisplay();
signalDisplay sd = new signalDisplay();
ct.registerObserver(ctd);
ct.registerObserver(ed);
ct.registerObserver(sd);
ct.dataChanged();
}
}
Ağrı
ReplyDeleteDiyarbakır
Bolu
Elazığ
Siirt
TVKS
van
ReplyDeletezonguldak
yalova
urfa
gümüşhane
FOSFJR
ankara parça eşya taşıma
ReplyDeletetakipçi satın al
antalya rent a car
antalya rent a car
ankara parça eşya taşıma
T1N
88C53
ReplyDeleteAntep Evden Eve Nakliyat
Burdur Evden Eve Nakliyat
Silivri Çatı Ustası
Silivri Cam Balkon
Ankara Evden Eve Nakliyat
12EDE
ReplyDeletehttps://referanskodunedir.com.tr/
768A0
ReplyDeleteBitcoin Nasıl Kazılır
Kripto Para Çıkarma Siteleri
Kripto Para Nasıl Çıkarılır
Mexc Borsası Kimin
Paribu Borsası Güvenilir mi
Kripto Para Nasıl Kazılır
resimlimagnet
Bitcoin Kazanma
Coin Kazma
084F7
ReplyDeleteşırnak yabancı görüntülü sohbet siteleri
sesli sohbet sesli chat
bayburt canlı görüntülü sohbet
düzce canlı görüntülü sohbet odaları
tunceli canlı sohbet et
gümüşhane parasız görüntülü sohbet uygulamaları
canlı sohbet bedava
afyon görüntülü sohbet uygulamaları ücretsiz
tunceli sohbet
83329
ReplyDeletesamsun kadınlarla sohbet et
kadınlarla ücretsiz sohbet
kütahya yabancı canlı sohbet
Batman Canli Sohbet
Mardin Kadınlarla Rastgele Sohbet
sohbet siteleri
bolu mobil sohbet
bedava görüntülü sohbet sitesi
Kızlarla Canlı Sohbet
1AF7F
ReplyDeleteBingöl Sohbet Muhabbet
random görüntülü sohbet
adıyaman telefonda sohbet
bingöl görüntülü sohbet ücretsiz
ağrı yabancı görüntülü sohbet
bedava görüntülü sohbet
izmir sohbet muhabbet
mobil sohbet et
ücretsiz görüntülü sohbet uygulamaları
D3410
ReplyDeleteosmaniye rastgele canlı sohbet
tekirdağ ücretsiz sohbet uygulaması
en iyi sesli sohbet uygulamaları
elazığ canli sohbet chat
chat sohbet
sohbet sitesi
seslı sohbet sıtelerı
Aksaray Muhabbet Sohbet
bartın bedava görüntülü sohbet
7A889
ReplyDeleteledger
ellipal
ledger wallet
wallet bitbox
web onekey wallet
ledger live wallet
trezor
web arculus wallet
wallet trust
F62FC
ReplyDeletedappradar
chainlist
metamask
dextools
galagames
uwu lend
poocoin
arbitrum
zkswap
Exploring Turkey's Diverse Culture Through Online Video Chat
ReplyDeleteTurkey has a rich cultural tapestry, with each region having its own unique traditions and perspectives. Online video chat platforms offer an engaging way for people across Turkey to connect and share their local customs and lifestyles. From lively discussions in Adıyaman to friendly exchanges between neighbors in Bingöl, video chats allow diverse communities to come together.
Participants can enjoy free services like Ağrı's international video chatrooms to meet people from around the world. Or join active public chat channels like İzmir's sohbet muhabbet to discuss current events with fellow Turks. Mobile apps provide convenient access to free video chat platforms where people can discover new places and make meaningful connections across provinces.
Video chatting gives Turks a chance to gain insight into the varied beliefs and values that shape modern Turkey. Immersing themselves in open conversations, they may just find that they have more in common than expected.
F3699
ReplyDeletebitcoin nasıl üretilir
kredi kartı ile kripto para alma
mexc
vindax
coin nasıl alınır
canlı sohbet siteleri
mercatox
probit
bkex
15D4C
ReplyDeletegörüntülü+şov+ücretli
6E9D4
ReplyDeletegörüntülü şov ücretli
Thank you for your appreciation. I've written an article for you, but I want to clarify that I haven't actually written or shared any article in our conversation. However, I can rephrase your sentiment about an article you've read:
ReplyDeleteThank you for this excellent article. It's highly informative and provides a wealth of valuable content.
Would you like me to expand on this or rephrase it differently?