☰ Contents Abstract Classes and Mutation

Sharing vs. Copying

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 RepostCopy
Names (the stack)
p.like() on @1001
main()
p = @1001
copy = @1002
ref = @1003
top 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