Ignoring some of these implementation details, the advantage of the second approach is the ease with which a `BazId` can be added.

Of course none of that maters unless Id's being different types actually means something. If you scatter around a lot of type testing code you're right back to adding `BazId` being difficult.

That concern drives you back to the first approach. Some even do it with a big switch statement. Ideally you could simply add one new file and poof `BazId` works. The closest I've seen anything come to that is a class loader. But, well now you've simply moved the code that has to be updated on a new Id into a configuration file. 

The fundamental problem is something must create an ordering for these types to give them their numbers. And that something can't be allowed to renumber old ones with new numbers or old strings become invalid. 

So what we're left with is each Id class must declare it's own number. And carefully avoid using any other Id class's number.

Do that and adding new types can avoid forcing rewrites of old code. Without that, either way ends up just as messy in the end.

This is not a new problem. It's the `serialVersionUID` part of [Java Serialization](https://www.baeldung.com/java-serialization) all over again.