Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct encapsulation in java object types

What is the correct encapsulation from below 2 classes in java?.I saw both these approches in many codes(mostly 1st approche). But seems like 2nd approach is the correct one.

import java.util.Date;

public class SomeClass
{
    private Date date;

    public Date getDate()
    {
        return date;
    }

    public void setDate(Date date)
    {
        this.date = date;
    }   
}

or

import java.util.Date;

public class SomeClass
{
    private Date date;

    public Date getDate()
    {
        return (Date) date.clone();
    }

    public void setDate(Date date)
    {
        this.date = (Date) date.clone();
    }

}
like image 944
Lakshitha Herath Avatar asked Jun 20 '13 06:06

Lakshitha Herath


2 Answers

It depends whether the type of the field you get/set is immutable or not, i.e. if they can be modified after their construction.

The point behind the whole Getter/Setter paradigm is that the private/protected fields of an instance cannot be arbitrarily modified (or gained access to) by any external Class.

So, in your first example, a Class could acquire a reference to the private Date-field and then (since Date is not immutable) use Date's setTime(long) method to modify the Date, effectively bypassing the Setter method of SomeClass (and any side-effects it might have, e.g. performing validation, updating a GUI element etc).
In your second example this can't be done, since the external Class would only acquire a clone of the actual Date, so any modifications done after that would have no effect on the original private Date-field of SomeClass.

Bottom line:
It all depends on the type of your private/protected fields and what you are trying to achieve/prevent.


Points to keep in mind:

  • clone() will not always return a deep-clone of an Object (especially for complex Object, whose fields reference other mutable Objects etc). So it must be used with care (and awareness of its inner workings).

  • Primitive data-types and Strings are immutable, so there is no need for clone()ing when getting/setting fields of these types.

like image 113
gkalpak Avatar answered Nov 05 '22 09:11

gkalpak


Not a good idea to clone as -

  1. Generally clone method of an object, creates a new instance of the same class and copies all the fields to the new instance and returns it = shallow copy. Object class provides a clone method and provides support for the shallow copy. It returns ‘Object’ as type and you need to explicitly cast back to your original object.

  2. When you implement deep copy be careful as you might fall for cyclic dependencies.

  3. Clone is not for instantiation and initialization. It should not be taken as creating a new object. Because the constructor of the cloned objects may never get invoked in the process.

4.One more disadvantage (and many others.. :)), clone prevents the use of final fields.

5 . In a Singleton pattern, if the superclass implements a public clone() method, to prevent your subclass from using this class’s clone() method to obtain a copy overwrite it and throw a CloneNotSupportedException

So, Approach 1 is better than Approach 2

like image 27
Ishank Avatar answered Nov 05 '22 08:11

Ishank