One factor that makes Java so comfortable is that it's a safe language. This means that it is overrun with buffers, arrays out of bounds, illegal pointers, and other memory corruption
are automatically immune, and these errors plague unsafe languages such as C and C + +. In a safe language, when designing a class, you can know exactly whether the system
The constraints of these classes can remain true for what happens in other parts. This is impossible for a language that "treats all memory as a huge array."
There is a situation where a protective copy is needed:
public class Period
{
Private final Date StartTime;
Private finale Date EndTime;
Public Period (Date startTime, date endTime)
{
if (Starttime.compareto (EndTime) > 0)
{throw new IllegalArgumentException ("StartTime after endTime!"); }
This.starttime = StartTime;
This.endtime = EndTime;
}
PUBILC Date Start ()
{return this.starttime;}
Public Date End ()
{return this.endtime;}
}
This class appears to be an immutable class because the StartTime and Endtime domains are final, but it is not a strict immutable class, because the date class is not an immutable class.
If the client uses the period class that we define:
Date StartTime = new Date ();
Date EndTime = new Date ();
Period per = new Period (StartTime, endTime);
Endtime.setyear (78);
Originally we wanted period to be an immutable class with only the initialized state, but since the Date class is a mutable class, we get the final date StartTime domain reference
Object, and this object is a date class, we can change the state of the object, causing the state in the period instance object to change.
This time we have a protective copy of the constructor:
Public Period (Date startTime, date endTime)
{
This.starttime = new Date (Starttime.gettime ());
This.endtime = new Date (Endtime.gettime ());
if (This.startTime.compareTo (This.endtime) > 0)
{
throw new IllegalArgumentException ("StartTime after endTime!");
}
}
This will not affect the state of the instance object of the period class when you change the state of the Endtime object when using the client code as above.
But if the client uses such code Per.start (). Setyear (78); This also destroys the state of the Per object.
The end () method should also use a protective copy for the start () that returns the domain of the instance object.
Public Date Start ()
{
return new Date (Starttime.gettime ());
}
Public Date End ()
{
return new Date (Endtime.gettime ());
}
In this way, the period class that we define really becomes an immutable class, and its instance object is only initialized in that state.
The use of protective copies is for our code to be more robust, considering the malicious destruction of client code.
In general, when we want to define an immutable class, but the type of the domain of this class is indeed a mutable class, we need a protective copy when we define the constructor.
Also remember that the validation of the parameter validity should be after the protective copy.
39th: A protective copy if necessary