How to make a class immutable in java with a date field in it?

I created an immutable class with a date field. How can I guarantee that even the date field is immutable, since even if you made the end of the date field, you can still assign it a different value?

+6
source share
6 answers

In your getDate() method, return an instance of new Date() instead of the same instance.

 public Date getDate() { // Not correct. return this.date; // This will make your class mutable. // Instead use, return new Date(this.date.getTime()); // This will make sure your date field cannot be changed. } 
+6
source

This is an example of a Bean (class) with a fixed HAS-A date object.

  import java.util.Date; public class MyBean { private Date date; // Immutable Date Step 1 Make Private public MyBean(Date date) { // Immutable Date Step 2 If Set through Constructor then get a specialised (sub class) Date. this.date= getImmutableDate(date); // THIS METHOD RETURNS AN IMMUTABLE DATE } public MyBean(){} // Allow Default Constructor public Date getDate() { return date; } // Immutable Date Step 3- Allow setting of date only once!! public void setDate(Date date) { if(this.date==null) { this.date= getImmutableDate(date); } } /* Override all Setter methods of Date class. So even if user gets reference of Date Object it is not the original date object * it would be a modified date object whose all setter methods do nothing*/ private Date getImmutableDate(Date date) { /* This is an Anonymous Inner Class that extends java.util.Date class, it overrides all the setter methods * making the date object IMMUTABLE( ie setXXX has no effect) * */ date =new Date(date.getTime()){ private static final long serialVersionUID = 1L; @Override public void setYear(int year) {} @Override public void setMonth(int month) {} @Override public void setDate(int date) {} @Override public void setHours(int hours) {} @Override public void setMinutes(int minutes) {} @Override public void setSeconds(int seconds) {} @Override public void setTime(long time) {} }; return date; } 

}

+2
source

Here is a simple immutable class example in Java

 public final class Employee{ final String pancardNumber; public Employee(String pancardNumber){ this.pancardNumber=pancardNumber; } public String getPancardNumber(){ return pancardNumber; } } 

The above class is immutable because:

  • The class instance variable is final, i.e. we cannot change its value after creating the object.
  • The class is final, so we cannot create a subclass.
  • There are no setter methods, i.e. we have no way to change the value of an instance variable.

These points make this class immutable. In the case of the Date attribute, you can use the constructor to set the date with each new object and import the org.joda.time.DateTime class. This is a better version than java.util.Date because it is immutable. Using java.util.Date would be dangerous since it is a mutable class and we cannot control the calling thread (which can change it). Here is an example.

 public final class Bill { private final int amount; private final DateTime dateTime; public Bill(int amount, DateTime dateTime) { this.amount = amount; this.dateTime = dateTime; } public int getAmount() { return amount; } public DateTime getDateTime() { return dateTime; } } 
+1
source

Use protective copying. This means that if you need to pass the date to some other class, for example, using a method parameter or returned from a method, you must make a copy.

Making a copy of the Date is easy:

 new Date(myDate.getting()) 
0
source

Identify mutable instance variables (for example, date or hashmap) return new objects with copied contents for all mutable objects. Immutable variables can be returned safely without extra effort.

See below for an example:

 import java.util.Date; public final class ImmutableClass { /** * Integer class is immutable as it does not provide any setter to change its content * */ private final Integer immutableField1; /** * String class is immutable as it also does not provide setter to change its content * */ private final String immutableField2; /** * Date class is mutable as it provide setters to change various date/time parts * */ private final Date mutableField; //Default private constructor will ensure no unplanned construction of class private ImmutableClass(Integer fld1, String fld2, Date date) { this.immutableField1 = fld1; this.immutableField2 = fld2; this.mutableField = new Date(date.getTime()); } //Factory method to store object creation logic in single place public static ImmutableClass createNewInstance(Integer fld1, String fld2, Date date) { return new ImmutableClass(fld1, fld2, date); } //Provide no setter methods /** * Integer class is immutable so we can return the instance variable as it is * */ public Integer getImmutableField1() { return immutableField1; } /** * String class is also immutable so we can return the instance variable as it is * */ public String getImmutableField2() { return immutableField2; } /** * Date class is mutable so we need a little care here. * We should not return the reference of original instance variable. * Instead a new Date object, with content copied to it, should be returned. * */ public Date getMutableField() { return new Date(mutableField.getTime()); } @Override public String toString() { return immutableField1 +" - "+ immutableField2 +" - "+ mutableField; } } 

More details: http://www.javainterviewpoint.com/make-class-immutable-java/

0
source

java.time

Other answers are true when displaying strategies for fixing values ​​inside your objects.

Let me also recommend that you use modern java.time classes, not scary heritage classes. Use Instant instead of Date . Instead of Calendar use ZonedDateTime .

The java.time classes are created as immutable objects. Methods such as plus… , minus… , to… and with produce a new object, leaving the original intact. Classes do not have customization methods.

Bonus tip: in your own immutable classes, you might find it useful to follow the method naming patterns set by the java.time classes.


About java.time

The java.time framework is built into Java 8 and later. These classes supersede the nasty old legacy time classes such as java.util.Date , Calendar and SimpleDateFormat .

The Joda-Time project, now in maintenance mode , we recommend switching to the java.time classes.

To learn more, see the Oracle Tutorial . And search for qaru for many examples and explanations. JSR 310 specification .

Using the JDBC driver compatible with JDBC 4.2 or later, you can exchange java.time objects directly with your database. No need for strings or java.sql. * Classes.

Where to get java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is proof of possible future additions to java.time. Here you can find useful classes such as Interval , YearWeek , YearQuarter and more .

0
source

All Articles