CMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)Lecture 19:Issues in CopyingLast time:1.Intro to arrays2.Copying arrays and making arrays bigger3.Array lengths and out-of-bounds indexing4.Passing arrays and array elements to a functionThis lecture set:1.Privacy Leaks2.Different levels of copyCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)1Foo object Privacy Leaks (continued)public class MutableThing {…public void mutateMe() {…};}public class Foo {private MutableThing q = new MutableThing();…public MutableThing getQ(){return q;}}Consider following codeFoo f = new Foo ();MutableThing m = f.getQ();m.mutateMe();After this executes, what happens?This phenomenon is called a privacy leakPrivate instance variables can be modified outside classBehavior is due to aliasingHeapStackfmMutableThingobjectCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)2Fixing Privacy LeaksReturn copies of objects referenced by instance variablesTo fix getQ method in Foo:MutableThing getQ(){return new MutableThing(q);}This returns a copy of qChanges made to this copy will not affect originalHeapStackfmFoo object MutableThingobjectMutableThingobjectCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)3Reference CopyingPerson[] d = {new Person(“SGH”, …),new Person(“Shakira”, …)};Person[] e = d;HeapStackdSGHShakiraeCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)4Shallow CopyingPerson[] d = {new Person(“SGH”, …),new Person(“Shakira”, …)};Person[] e = new Person[d.length];for (int i=0; i < d.length, i++){e[i] = d[i];}HeapStackdSGHShakiraeCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)5Deep CopyingPerson[] d = {new Person(“SGH”, …),new Person(“Shakira”, …)};Person[] e = new Person[d.length];for (int i=0; i<d.length; i++) {e[i] = new Person(d[i]);}HeapStackdSGHShakiraeSGHShakiraCMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)6Three Ways of CopyingCDCollector contains an array of CD’s;ReCDCollector contains an array of rewritableCD’s;Reference copypublic ReCD[] getCDsReferenceCopy() {return myFavorites;}Shallow copypublic ReCD[] getCDsShallowCopy() {ReCD[] copy = new ReCD[myFavorites.length];for (int i = 0; i < copy.length; i++)copy[i] = myFavorites[i];return copy;}Deep copypublic ReCD[] getCDsDeepCopy() {ReCD[] copy = new ReCD[myFavorites.length];for (int i = 0; i < copy.length; i++)copy[i] = new ReCD(myFavorites[i]);return copy;}ReCDCollectionOwner p = new RECD…;ReCD[] a = p.getCD…();a[0] = otherCDalreadycreated;a[0].rewrite(“other”,”name”);CMSC 131 Fall 2007Jan Plane (adapted from Bonnie Dorr)7When To Use What Kind of Copying?Reference copying is usually a bad idea (not always but realize what you are doing)Deep copying provides maximal protection against aliasing (but takes a lot of time and space if it was not necessary)Storage space and time usedReference: leastShallow: middleDeep: mostIf the class is mutable, aliasing is something to be avoided and you must have true copies to prevent privacy leaks and modifications outside.If you know the class is immutable, aliasing doesn’t hurt but neither does making true copies (except wasted space and time).If storage is an issue, aliasing problems may be worth coping with but must be well
View Full Document