A Broken Time Period Class

Computer Science and Engineering „ The Ohio State University public class Period { private Date start; Immutable Classes private Date end; Computer Science and Engineering „ College of Engineering „ The Ohio State University public Period(Date start, Date end) { assert (start.compareTo(end) > 0); //start < end

this.start = start; this.end = end; Lecture 8 }

public Date getStart() { return start; }

public Date getEnd() { return end; } }

Questions Problem: Aliasing

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University † What is an invariant in general? † Assignment in constructor creates an alias „ Ans: „ Client and component both have references to the same Date object † Class invariant can be undermined via alias † What is an invariant for class Period? Date start = new Date(300); „ Ans: Date end = new Date (500); Period p = new Period (start, end); end.setTime(100); //modifies internals of p † Why is this an invariant for this class? † Solution: “defensive copying” „ Ans: „ Constructor creates a copy of the arguments „ Copy is used to initialize the private fields „ Metaphor: ownership

A Better Period Class Good Practice: Copy First

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University public class Period { private Date start; † When making a defensive copy of private Date end; constructor arguments: public Period(Date start, Date end) { „ First copy the arguments assert (start.compareTo(end) > 0); //start < end „ Then check the validity of the parameters this.start = new Date(start.getTime()); this.end = new Date(end.getTime()); † Reason: multithreaded code } „ Consider a constructor that checks first, public Date getStart() { return start; then copies } „ Another thread of execution could change public Date getEnd() { the parameters after they pass the validity return end; } check, but before they are copied into the } private fields

1 A Better+1 Period Class Problem: Aliasing

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University public class Period { private Date start; † Return value in accessor creates an alias private Date end; „ Client can still obtain a reference to the class’s internal representation (the private fields) public Period(Date start, Date end) { this.start = new Date(start.getTime()); „ aka “privacy leak”, but really just an alias problem this.end = new Date(end.getTime()); † Class invariant can be undermined via alias assert (this.start.compareTo(this.end) > 0); Date start = new Date(300); } Date end = new Date (500); public Date getStart() { Period p = new Period (start, end); return start; } p.getEnd().setTime(100); //modifies p’s rep

public Date getEnd() { † Solution: “defensive copying” return end; „ Accessors create a copy of internal fields } } „ Copy is returned to the client

A Better+2 Period Class Immutability

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University public class Period { private Date start; † An immutable object is one whose value can private Date end; not change

public Period(Date start, Date end) { „ Constructor allows initialization to different values this.start = new Date(start.getTime()); „ No mutator methods this.end = new Date(end.getTime()); † ie No alters clauses containing “this” assert (this.start.compareTo(this.end) > 0); } † Why would we want such a thing? † Because aliasing an immutable is safe! public Date getStart() { return new Date(start.getTime()); „ Having multiple references to the same immutable } is indistinguishable from having multiple public Date getEnd() { references to different immutables that have the return new Date(end.getTime()); same value } „ Defensive copies of immutables are not required }

How to Write an Immutable Class Examples

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University † Do not provide mutators † Period „ Check alters clause of all methods „ Has fields that refer to mutables (Date) „ Needs defensive copies † Make all fields private † String „ You do that anyway, right? „ Lots of methods look like they could be mutators † Ensure exclusive access to any † eg toUpperCase(), substring(int,int), mutable objects referred to by fields replace(char,char) „ But these methods actually return a String „ If the class has fields that refer to mutable String str = new String(“Hello there”); objects, make defensive copies in System.out.println(str.toUpperCase()); constructors and for return values from † Wrapper classes methods „ Integer, Long, Float, etc…

2 Good Practice: Immutable Idioms A Better+3 Period Class

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University public class Period { † Declare all fields to be final private final Date start; „ Guarantees immutability for primitives private final Date end; public Period(Date start, Date end) { „ For reference type it is no help, but still this.start = new Date(start.getTime()); considered an idiom signaling the intent to this.end = new Date(end.getTime());

write an immutable class assert (this.start.compareTo(this.end) > 0); † Declare class to be “final” } public Date getStart() { „ We will talk about what this qualifier return new Date(start.getTime()); means for classes later }

public Date getEnd() { return new Date(end.getTime()); } }

Wrapper Classes Boxing and Unboxing

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University † Every primitive type has a corresponding † Boxing: primitive --> wrapper wrapper class Integer integerObject = new Integer(42); „ Integer, Long, Float, Double, … † Unboxing: wrapper --> primitive † The classes are immutable † int i = integerObject.intValue(); „ So no aliasing worries † does this automatically for you † Do not provide a zero-argument constructor Double price = 499.99; //auto-box † Do provide useful static constants price = price + 19.90; //auto-unbox then box „ Integer.MAX_VALUE, Integer.MIN_VALUE „ But be very careful… Integer i = new Integer(2); † Do provide useful static methods Integer j = new Integer(2); „ Converting from String to primitive: parseInt() assertTrue(i >= j); //success (unboxing) † int i = Integer.parseInt(“33342”); assertTrue(i <= j); //success (unboxing) „ Converting from primitive to String: toString() assertTrue(i == j); //failure! (no unboxing) † String str = Double.toString(123.99);

Supplemental Reading Summary

Computer Science and Engineering „ The Ohio State University Computer Science and Engineering „ The Ohio State University † Bloch’s “Effective Java” † Defensive copying „ Item 13: Favor Immutability „ Copy constructor arguments (reference types) „ Return only copies of fields (reference types) „ Item 24: Make defensive copies when needed † Immutable classes „ Each instance represents a distinct value „ No mutators: no methods alter “this” † Methods can return a new instance „ Defensive copying of mutable fields † Examples of immutables „ String „ Wrapper classes (Integer, Long, Float…) † Auto-boxing / auto-unboxing

3