Student: I have a question – when I make a repost on Instagram, does it make a copy of the post or does it store something more like a reference?
Prof: More like a reference. It probably stores something like a “post id number” of the original post. Why do you ask?
Student: Well I was thinking about how that would look in Java.
Prof: Oh that’s a good question. They’d look pretty different, here’s how I’d think of them:
Prof: What are some things you notice and wonder about here?
Student: Well, the printed out likes are different for the last three lines.
Prof: Which one didn’t change, the copy or the reference?
Student: Um, the copy didn’t change. Oh, interesting. Because it made a new object with its own
likes field?Prof: Right. If we look at the memory diagram when we call
p.like(), we can see that we’re updating a reference that is aliased with the RepostRef object but not with the RepostCopy object. So the change doesn’t show up when we look at the RepostCopyNames (the stack)
p.like() on @1001main()p = @1001copy = @1002ref = @1003top level
Heap
@1001: Post[user=joe, message=CSE-PACE next Tuesday!, likes=22 23]@1002: RepostCopy[user=ana, originalUser=joe, message=CSE-PACE next Tuesday!, likes=22]@1003: RepostRef[user=ben, original=@1001]Student: I see! So that really is like there is one orginal post, if we use the ref. And when you like a repost, it likes the original.
Prof: Right, and that’s why resharing ought to have a reference to the original, not a copy of its contents.
Practice
Here are the two reposts again, this time with the tags array and retag from before:
class Post {
String user;
String message;
String[] tags;
Post(String user, String message, String[] tags) {
this.user = user;
this.message = message;
this.tags = tags;
}
void retag(String[] newTags) { this.tags = newTags; }
RepostCopy repostCopy(String reposter) {
return new RepostCopy(reposter, user, message, tags);
}
RepostRef repostRef(String reposter) {
return new RepostRef(reposter, this);
}
}
class RepostCopy {
String user;
String originalUser;
String message;
String[] tags;
RepostCopy(String user, String originalUser, String message, String[] tags) {
this.user = user;
this.originalUser = originalUser;
this.message = message;
this.tags = tags;
}
}
class RepostRef {
String user;
Post original;
RepostRef(String user, Post original) {
this.user = user;
this.original = original;
}
}
String[] a = {"cse11", "java"};
String[] b = {"pizza"};
Post p = new Post("joe", "Free pizza in the CSE lobby", a);
RepostCopy copy = p.repostCopy("ana");
RepostRef ref = p.repostRef("ben");
void main() {
a[1] = "food";
p.retag(b);
}After
main runs:copy.tags is the same array as ref.original.tags is the same array as copy.tags[1] is ref.original.tags[0] is