> > Part 4-Core Java Interview Questions and Answers (HashCode & equals())
What is a Cloneable interface and what all methods does it contain?
Cloneable is a declaration that the class implementing it allows cloning or bitwise copy of it's object state. It is not having any method because it is a Marker interface.
How clone method works in Java?
The clone() method from java.lang.Object class is used to create a copy of an Object in Java. This copy is known as a clone of original instance. Constructor is not called during cloning of Object in Java.
clone() method is declared as protected and native in Object class. Since its convention to return clone() of an object by calling super.clone() method, any cloning process eventually reaches to java.lang.Object clone() method.
A clone object should follow basic characteristics:
1). a.clone() != a, which means original and clone are two separate object in Java heap.
2). a.clone().getClass() == a.getClass()
3). a.clone().equals(a), which means clone is exact copy of original object.
Above three characteristic is followed by a well behaved, correctly overridden clone() method in Java, but it's not enforced by the cloning mechanism. Which means, an object returned by clone() method may violate any of these rules.
By following the convention of returning an object by calling super.clone(), when overriding clone() method, you can ensure that it follows first two characteristics. In order to follow the third characteristic, you must override equals method to enforce logical comparison, instead of physical comparison exists in java.lang.Object.
Difference between shallow cloning and deep cloning of objects?
Cloning in Java can be grouped into two categories: Shallow and Deep Cloning
clone() method, first checks if the corresponding object implements Cloneable interface, which is a marker interface. If that instance doesn't implement Cloneable then it throws a checked exception CloneNotSupportedException. Else, java.lang.Object's clone() method creates a shallow copy of the object and returned it to the caller.
Since Object class' clone() method creates copy by creating new instance, and then copying field-by-field, similar to assignment operator, it's fine for primitives and Immutable object, but not suited if your class contains some mutable data structure e.g. Collection classes like ArrayList or arrays. In that case, both original object and copy of the object will point to the same object in the heap. You can prevent this by using the technique known as deep cloning, on which each mutable field is cloned separately.
e.g
clone() of Date object?
java.util.Date.clone() method of Date class in Java returns the duplicate of the passed Date object. This duplicate is just a shallow copy of the given Date object.
Why the singleton class should never implement Cloneable interface?
Because Singleton implementation doesn't restrict it from cloning and hence we can have multiple objects when we actually don't intend it to have multiple objects.
Which classes in java are immutable?
String and all wrapper classes in java.lang (such as Integer, Boolean, Character, Byte, Short, Long, Float, Double, BigDecimal, BigInteger) are immutable. Also LocalDate, LocalTime and LocalDateTime classes (since 1.8) are also immutable.
What are the advantages of immutability?
Only declaring primitive types as final makes them immutable. Making objects final means that the object handler cannot be used to target some other object but the object is still mutable.
How to create Immutable Class and Object in Java?
First of all let us understand what immutable class or object is? Immutable classes are those class, whose object can not be modified once created, it means any modification on immutable object will result in another immutable object. e.g. java.lang.String, once created can not be modified. All modification (e.g. trim, uppercase, lowercase) in String result in new object.
Example of immutable class: SecretDetails is immutable, because the state of class can not be changed once created, we havedeclated all of it’s fields as final.
public final class SecretDetails {
private final String employeename;
private final int employeeage;
public SecretDetails(String employeename, int employeeage) {
this.employeename = employeename;
this.employee = employee;
}
public String getEmployeename(){
return employeename;
}
public String getEmployeeage(){
return employeeage;
}
}
What if your immutable class includes a mutable classes like java.util.Date?
Despite storing Date into final field, it can be modified internally, if internal date is returned to the client. In order to preserve immutability in such cases, its advised to return copy of original object, which is also one of the Java best practice.
ALSO READ: Why String is immutable or Final in Java?
e.g in ImmutableReminder if getRemindingDate() returns actual Date object than despite remindingDate being final variable, internals of Date can be modified by client code. By returning clone() or copy of remindingDate, we avoid that danger and preserves immutability of class.
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
OR add a getter method for Date like this:
public Date getRemindingDate() {
return new Date(this.remindingDate.getTime());
}
Here are few things that we must consider for making an immutable class:
Cloneable is a declaration that the class implementing it allows cloning or bitwise copy of it's object state. It is not having any method because it is a Marker interface.
How clone method works in Java?
The clone() method from java.lang.Object class is used to create a copy of an Object in Java. This copy is known as a clone of original instance. Constructor is not called during cloning of Object in Java.
clone() method is declared as protected and native in Object class. Since its convention to return clone() of an object by calling super.clone() method, any cloning process eventually reaches to java.lang.Object clone() method.
A clone object should follow basic characteristics:
1). a.clone() != a, which means original and clone are two separate object in Java heap.
2). a.clone().getClass() == a.getClass()
3). a.clone().equals(a), which means clone is exact copy of original object.
Above three characteristic is followed by a well behaved, correctly overridden clone() method in Java, but it's not enforced by the cloning mechanism. Which means, an object returned by clone() method may violate any of these rules.
By following the convention of returning an object by calling super.clone(), when overriding clone() method, you can ensure that it follows first two characteristics. In order to follow the third characteristic, you must override equals method to enforce logical comparison, instead of physical comparison exists in java.lang.Object.
Difference between shallow cloning and deep cloning of objects?
Cloning in Java can be grouped into two categories: Shallow and Deep Cloning
clone() method, first checks if the corresponding object implements Cloneable interface, which is a marker interface. If that instance doesn't implement Cloneable then it throws a checked exception CloneNotSupportedException. Else, java.lang.Object's clone() method creates a shallow copy of the object and returned it to the caller.
Since Object class' clone() method creates copy by creating new instance, and then copying field-by-field, similar to assignment operator, it's fine for primitives and Immutable object, but not suited if your class contains some mutable data structure e.g. Collection classes like ArrayList or arrays. In that case, both original object and copy of the object will point to the same object in the heap. You can prevent this by using the technique known as deep cloning, on which each mutable field is cloned separately.
e.g
clone() of Date object?
java.util.Date.clone() method of Date class in Java returns the duplicate of the passed Date object. This duplicate is just a shallow copy of the given Date object.
Why the singleton class should never implement Cloneable interface?
Because Singleton implementation doesn't restrict it from cloning and hence we can have multiple objects when we actually don't intend it to have multiple objects.
Which classes in java are immutable?
String and all wrapper classes in java.lang (such as Integer, Boolean, Character, Byte, Short, Long, Float, Double, BigDecimal, BigInteger) are immutable. Also LocalDate, LocalTime and LocalDateTime classes (since 1.8) are also immutable.
What are the advantages of immutability?
- Immutable objects are automatically thread-safe, the overhead caused due to use of synchronisation is avoided.
- Once created the state of the immutable object can not be changed so there is no possibility of them getting into an inconsistent state.
- The references to the immutable objects can be easily shared or cached without having to copy or clone them as there state can not be changed ever after construction.
- The best use of the immutable objects is as the keys of a map.
Only declaring primitive types as final makes them immutable. Making objects final means that the object handler cannot be used to target some other object but the object is still mutable.
How to create Immutable Class and Object in Java?
First of all let us understand what immutable class or object is? Immutable classes are those class, whose object can not be modified once created, it means any modification on immutable object will result in another immutable object. e.g. java.lang.String, once created can not be modified. All modification (e.g. trim, uppercase, lowercase) in String result in new object.
Example of immutable class: SecretDetails is immutable, because the state of class can not be changed once created, we havedeclated all of it’s fields as final.
public final class SecretDetails {
private final String employeename;
private final int employeeage;
public SecretDetails(String employeename, int employeeage) {
this.employeename = employeename;
this.employee = employee;
}
public String getEmployeename(){
return employeename;
}
public String getEmployeeage(){
return employeeage;
}
}
What if your immutable class includes a mutable classes like java.util.Date?
Despite storing Date into final field, it can be modified internally, if internal date is returned to the client. In order to preserve immutability in such cases, its advised to return copy of original object, which is also one of the Java best practice.
ALSO READ: Why String is immutable or Final in Java?
e.g in ImmutableReminder if getRemindingDate() returns actual Date object than despite remindingDate being final variable, internals of Date can be modified by client code. By returning clone() or copy of remindingDate, we avoid that danger and preserves immutability of class.
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
OR add a getter method for Date like this:
public Date getRemindingDate() {
return new Date(this.remindingDate.getTime());
}
Here are few things that we must consider for making an immutable class:
- Make your class final (So that child classes can’t be create)
- Make all the fields private and final(So that we can’t change the value of it after object creation)
- Don't declare any methods that change the state of your instance (no setter's to not have the option to change the value of the instance variable)
- If you have mutable fields in your class, like List, or Date, making them final won't suffice. You should return a defensive copy from their getters, so that their state isn't mutated by calling methods.
Advantages of Immutable Objects:
1) Immutable objects are by default thread safe, can be shared without synchronization in concurrent environment.
2) Immutable object simplifies development, because its easier to share between multiple threads without external synchronization.
3) Immutable object boost performance of Java application by reducing synchronization in code.
4) Another important benefit of Immutable objects is reusability, you can cache Immutable object and reuse them, much like String literals and Integers.
However, immutable object has disadvantage of creating garbage as well. Since immutable object can not be reused and they are just a use and throw.
thank u
ReplyDeleteThank you Mr. Shukla
ReplyDelete