CS242 Advanced Programming Concepts in Java - PowerPoint PPT Presentation

1 / 41
About This Presentation
Title:

CS242 Advanced Programming Concepts in Java

Description:

Have used the bitwise, shallow copy. So the references still point to the same exact objects. ... call Object.clone() to make a bitwise copy of the swimmer ... – PowerPoint PPT presentation

Number of Views:34
Avg rating:3.0/5.0
Slides: 42
Provided by: janicets
Category:

less

Transcript and Presenter's Notes

Title: CS242 Advanced Programming Concepts in Java


1
CS242Advanced Programming Concepts in Java
  • 11/01/07
  • I/O and Cloning

Prof. Searleman jets_at_clarkson.edu
2
Outline
  • Java I/O
  • Binary I/O StreamReader, StreamWriter
  • Text streams unicode
  • Cloning
  • Reading
  • - Java Technical Tips, Cloning objects
  • (http//java.sun.com/developer/JDCTechTips/2001/tt
    0306.html)
  • - Effective Java Item 10
  • - OODP, p. 112-113 Chap. 7, pp. 280 - 285
  • HW5 posted, team (of 2), due 11/13/07
  • Review session for Exam1 tonight, 700 pm, ITL

3
Binary Data
  • Use DataOutputStream to create a binary file
    then use DataInputStream to read in data from
    that binary file
  • Use Object Input/Output streams for
    serialization
  • Use Zip or GZip Input/Output streams for file
    compression

4
  • // Example create a gzipped output file
  • DataOutputStream outFile
  • new DataOutputStream(
  • new BufferedOutputStream(
  • new GZIPOutputStream(
  • new FileOutputStream(mydata.gz)))
  • int c
  • while((c in.read()) ! -1)
  • outFile.write(c)
  • outFile.close()
  • // Exercise read in and print the data in this
    file

5
Text Streams
  • consider the text 1342
  • Unicode 00 31 00 33 00 34 00 32
  • most environments use their own char encoding
    e.g. windows 31 33 34 32
  • Java provides conversion filters from Unicode to
    the char encoding used by the local OS

6
Input/Output StreamReader revisited
  • InputStreamReader converts an input stream
    containing bytes in a particular char encoding
    into a reader that emits Unicode chars
  • OutputStreamReader is similar

7
  • e.g. read keystrokes from console (recall that
    System.in is an InputStream), and convert to
    Unicode
  • A..Z \u0041 .. \u005a
  • a..z \u0061 .. \u007a
  • 0..9 \u0030 .. \u0039
  • InputStreamReader isr
  • new InputStreamReader(System.in)
  • int x isr.read()
  • user types 4 what is x (in decimal)?

52 (hex 34)
8
Other encodings
new InputStreamReader( new FileInputStream(myd
ata, 8859_5)
9
Cloning making safe copies
  • Item 10 Override clone judiciously
  • Cloneable interface
  • clone() method
  • shallow vs. deep cloning
  • in addition to the Effective Java text, also
  • read OODP, p. 112-113 Chap. 7, pp. 280 - 285

10
  • // consider the following class
  • public class Swimmer
  • private String name
  • private float swimTime
  • private Date eventDate
  • public Swimmer()
  • public String getName() return name
  • public float getSwimTime() return swimTime
  • public Date getEventDate() return eventDate

11
  • // application programmer writes
  • Swimmer cu1 new Swimmer()
  • Date d cu1.getEventDate()
  • d.setYear(1982) // problem!! Date is mutable
  • Its not just that setYear() is deprecated (we
    can adjust for that by using calendar class) the
    more serious problem is that we have broken
    encapsulation
  • This is true even if the fields are made final

12
Swimmer
String
Kristen
name
swimTime
26.31
eventDate
Date
year
2007
1982
etc.
13
Aliasing problem
  • both d and cu1.eventDate refer to the same exact
    object
  • so, if you change one, you change the other
  • solution accessor should return a clone
    (copy) of the event date
  • is this a problem for the name field?
  • clone() makes a copy of an object the question
    is what kind of copy?

14
Object cosmic superclass
  • public final Class getClass()
  • public int hashCode()
  • public boolean equals(Object obj)
  • public String toString()
  • protected Object clone() throws
  • CloneNotSupportedException

15
protected Object clone() throws
CloneNotSupportedException
  • Creates and returns a copy of this object. The
    precise meaning of "copy" may depend on the class
    of the object. The general intent is that, for
    any object x
  • x.clone() ! x
  • will be true, and that the expression
  • x.clone().getClass() x.getClass()
  • will be true, but these are not absolute
    requirements. While it is typically the case
    that
  • x.clone().equals(x)
  • will be true, this is not an absolute
    requirement.

16
Object.clone()
  • makes a field-by-field, bit-by-bit copy of a
    cloneable object
  • throws CloneNotSupportedException for any class
    which doesnt implement cloneable
  • java.lang.Object declares its clone() protected
    and native gt can call Object.clone() the
    native method that duplicates the object only
    from within the object being cloned

17
Cloneable interface
  • the Cloneable interface is a marker interface
    it has no methods!
  • the purpose of a marker interface is allow you to
    use instanceof in a type inquiry
  • if (x instanceof Cloneable)
  • repeat clone() is not in the Cloneable interface
    (unlike Comparable) the clone() method is in
    class Object

18
Cloning dice
  • Die d1 new Die()
  • Die d2 (Die) d1.clone() // ERROR
  • need to do the following
  • implement Cloneable interface
  • override Object.clone() method

19
  • public class Die
  • implements Cloneable, Comparable
  • public Object clone()
  • try
  • return super.clone()
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())
  • // etc.

20
Cloning swimmer
  • Its not enough to use the Object cloning method,
    since it only makes a shallow copy

21
  • public class Swimmer
  • implements Cloneable, Comparable
  • public Object clone()
  • try
  • return super.clone()
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())
  • // etc.

22
Cloning swimmers
  • Swimmer s1 new Swimmer()
  • Swimmer s2 (Swimmer) s1.clone()
  • Whats the problem?
  • Have used the bitwise, shallow copy. So the
    references still point to the same exact objects.
  • Not a problem for immutable objects, but is
    problematical for mutable objects

23
(No Transcript)
24
Cloning swimmer
  • call Object.clone() to make a bitwise copy of the
    swimmer
  • cast the result to Swimmer so that the eventDate
    instance variable can be cloned
  • clone the eventDate
  • return the result

25
  • public class Swimmer
  • implements Cloneable, Comparable
  • public Object clone()
  • try
  • Swimmer s (Swimmer) super.clone()
  • s.eventDate (Date) eventDate.clone()
  • return s
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())

26
It is up to the class designer to determine
whether
  • the default clone() is good enough
  • Shallow cloning
  • the default clone() can be patched up by calling
    clone on each non-primitive, mutable instance
    variable
  • Deep cloning
  • give up dont use clone

27
Case 1 shallow cloning
  • Default clone is good enough
  • All instance variables are either primitive
    values or immutable objects, and every superclass
    up to Object is well-behaved
  • implement Cloneable interface
  • in the class, define a method
  • public Object clone() that calls
  • super.clone() and returns that copy

28
  • public class X
  • implements Cloneable
  • public Object clone()
  • try
  • return super.clone() // shallow clone
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())

29
Case 2 deep cloning
  • The default clone can be patched up
  • implement Cloneable interface
  • in your class, define a method
  • public Object clone()
  • that calls super.clone() to make a shallow copy,
    plus makes deep copies of fields that refer to
    mutable objects by calling clone() individually
    on those fields

30
  • public class X implements Cloneable
  • private int a // primitive
  • private String b // reference to immutable
    object
  • private Y c // where class Y has mutator
    methods
  • private Z d // where class Z has mutator
    methods
  • public Object clone() // deep clone
  • try
  • X other (X) super.clone() // fields a
    b OK
  • other.c (Y) c.clone() // fix c by making
    a copy
  • other.d (Z) d.clone() // fix d by making
    a copy
  • return other // return the deep clone
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())

31
Case 2 deep cloning requirements
  • the example depends on classes Y and Z having
    the ability to clone
  • cannot fix any field which is final

32
Case 3 dont use cloning
  • even if all fields are primitive and/or
    immutable objects, there may still be problems
  • e.g. timestamps, unique serial ,
  • Consider providing a copy constructor or a static
    factory method
  • (cf. Effective Java Programming Language Guide,
    pp. 45-52)

33
  • public class Swimmer implements Cloneable
  • private String name
  • private float swimTime
  • private Date eventDate
  • public Swimmer()
  • public String getName() return name
  • public float getSwimTime() return swimTime
  • public Object clone() / case 2 deep clone
    /
  • public Date getEventDate()
  • return (Date) eventDate.clone()
  • // note Date is cloneable

34
What about arrays?
  • public class CloneDemo6
  • public static void main(String args)
  • int vec1 new int1, 2, 3
  • int vec2 (int)vec1.clone()
  • System.out.println(vec20 " "
  • vec21 " " vec22)

Note all arrays are considered to implement the
cloneable interface
35
Cloning an array of objects
  • public class DiceGame
  • private Die dice new Die5
  • for (int i 0 i lt dice.length i)
  • dice0 new Die(i6)
  • Need a deep copy to clone DiceGame

36
To clone an array of Objects
  • clone the array, then
  • clone each object in the array
  • Similar for cloning Collections

37
  • public class A implements Cloneable
  • private Map map
  • public A()
  • map new HashMap()
  • map.put("key1", "value1")
  • map.put("key2", "value2")
  • public Object clone()
  • try
  • A other (A)super.clone()
  • other.map (HashMap)map.clone()
  • return other
  • catch (CloneNotSupportedException e)
  • throw new InternalError(e.toString())

38
  • public class CloneDemo5
  • public static void main(String args)
  • A obj1 new A()
  • A obj2 (A)obj1.clone()
  • obj1.map.remove("key1")
  • System.out.println(obj2.map.get("key1"))

39
  • public class CloneDemo8
  • private int a
  • private int b
  • private final long c
  • public CloneDemo8(int a, int b)
  • this.a a
  • this.b b
  • this.c System.currentTimeMillis()
  • // how to clone this so that the copy has
  • // the correct timestamp? cant

40
  • // instead of cloning, provide a copy
  • // constructor
  • public CloneDemo8(CloneDemo8 obj)
  • this.a obj.a
  • this.b obj.b
  • this.c System.currentTimeMillis()

41
Things to remember
  • cloning is a way to create and initialize an
    object, but its fundamentally different from
    calling a constructor
  • MUST call super.clone (not a constructor)
  • final fields are problematical
  • must consider whether shallow cloning is
    sufficient, or a deep clone is required
  • arrays collections of objects require deep
    cloning
  • consider providing a copy constructor
Write a Comment
User Comments (0)
About PowerShow.com