why java records aren’t quite immutable

A new type called a “record” was previewed in Java 14 and released in Java 16. One of the benefits is that it creates immutable objects. Kind of.

An immutable record

This is record is an immutable object. Since it is a record, it is automatically final and has no setters. All is good.

public record Book (String title, int numPages) { }

A mutable record

There there is this record. Do you see why it is mutable?

public record Book (String title, int numPages, List<String> chapters) { }

The problem is that records use shallow immutability. The caller can’t change the “chapters” object to a different reference. The caller can change the values in the “chapters” to their heart’s content. That means this object is still mutable.

Here’s an example showing that the code prints [1, 2, 3] and therefore changes the list of chapters.

List<String> chapters = new ArrayList<>();
chapters.add("1");

Book book = new Book("Breaking and entering", 289, chapters);

chapters.add("2");
book.chapters().add("3");
System.out.println(book.chapters());

Making the record actually be immutable

It’s pretty easy to make the Book record actually be immutable. In fact, it only requires three extra lines! Records have a compact constructor which takes care of the setting fields for you. However, you can choose to change that behavior. In this example, I rely on the default set of “title” and “numPages”. However, for “chapters”, I choose to make an immutable copy to prevent changing the list.

public record Book (String title, int numPages, List<String> chapters) {

    public Book {
        chapters = List.copyOf(chapters);
    }
}

Now the test program fails with an UnsupportedOperationException. Much better. A real immutable record.

Setting java aliases with zshell on Mac

When I’m working on different versions of Java, I set up a bunch of aliases so I can run commands quickly and compare differences. I recently upgraded my Mac and accepted the default shell as zshell instead of bash. (This change was made a long time ago but I didn’t upgrade for a long time because I didn’t want to incur the risk of being without my computer when everything was closed for the pandemic.)

Since I needed to move this from .bash_profile to .zshenv, I took the opportunity to shed a lot of them. I now have just Java 11 and Java 17 that I am using for comparisons. (LTS to LTS).

My .zshenv now contains this. (Yes, I know I should have patched Java 11, but alas.) I ran “source .zshenv” and am good to go.

Now I can run java11 JeanneTest.java and java17 JeanneTest.java to easily compare differences.

alias javac17=/Library/Java/JavaVirtualMachines/jdk-17-ea.jdk/Contents/Home/bin/javac
alias java17=/Library/Java/JavaVirtualMachines/jdk-17-ea.jdk/Contents/Home/bin/java
alias jar17=/Library/Java/JavaVirtualMachines/jdk-17-ea.jdk/Contents/Home/bin/jar
alias javac11=/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/javac
alias java11=/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/java
alias jar11=/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/jar
alias jshell11=/Library/Java/JavaVirtualMachines/jdk-11.0..jdk/Contents/Home/bin/jshell
alias jdeps11=/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/jdeps
alias jmod11=/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/jmod

export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk-17-ea.jdk/Contents/Home"

our first toastmasters post-pandemic hybrid meeting

Before the pandemic, our club mainly met over a video conference between our NY and NJ office. Everyone was in one of those rooms. (We had a couple other formats, but they were rare.)

Shortly before the pandemic, we talked about adding a phone option for people who would be telecommuting that day. But we shut down too fast for that to grow legs.

Last week, we had our first post-pandemic hybrid meeting. We used the same WebEx link that we’ve been using for the last 16 months. We also had a meeting room in the invite for anyone who happened to be onsite. (We are doing a pilot where a small number of people are onsite.

How it went

  • We had three people in the meeting room. (spread out). We were all visible in the pane of the WebEx representing the room.
  • We had about a dozen people in their homes.
  • Our club mascot (stuffed animal) also attended the meeting in person. He was super excited to be there after spending all that time alone in a file cabinet :).
  • When we were doing pure virtual meetings, we did introductions by having the Toastmaster say each person’s name (based n the participant list) and that person saying their group (we are a corporate club) and a quick fact. With hybrid, the Toastmaster had the people in the room go in a circle to introduce themselves and then did it based on the participant list. This approach is not ideal for a team meeting because it makes the in person participants seem more “central”, but I think it is ok for a Toastmasters meeting.
  • When we did introductions, I brought the mascot right up to the camera and had him wave so everyone could get a good view. (Anyone who joined during the pandemic was seeing the mascot for the first time.)
  • It so happened that one of the speakers (me) was in the physical room along with the Toastmaster. We also had a table topics speaker in the room.
  • We did not shake hands or touch in any way. (We had stopped doing that a little before we went virtual only)

What did I learn about speaking at a hybrid meeting

First, I learned that public speaking is like riding a bike. It came right back to me. Phew.

Additionally, I treated the conference room webcam as if it was a participant in the room. I stood in a place where I was clearly visible to the webcam. (Which was not the head of the table because it is a very long room and we don’t have zoom working yet.) I also made eye contact with the two people and the webcam. So I treated the webcam as if it were an actual person in the room.

What do I think will happen in the future

I think we will have more than three people in the room. But I think we will stay hybrid forever. The odds of everyone who wants to be in Toastmasters being in the office the day we meet seem low. And public speaking at work will involve a mix of in person and remote. So good to practice it.

We used to have Speakouts on Mondays so that people who weren’t in the office on Thursdays had an opportunity to speak. I think we will go back to something similar. Except rather than it always being Monday, have the day rotate. That way members who are only in the office once a week will still get to practice speaking in person.

I also think we will encourage members to meet in small groups at each give a speech. This will introduce more flexibility in speaking in person days they are in the office. It will also accommodate those who don’t feel comfortable being in a room with a lot of people for health reasons. Three people in a room is less risk than “whomever shows up for Toastmasters that day.” Notice I said health reasons. If someone merely doesn’t feel comfortable speaking in front of a group, that’s something to get over in Toastmasters!