'. '


From APIDesign

Jump to: navigation, search

Enums in APIs

As Jesse explains, a client API should generally use final classes, which, among other advantages, are more flexible from the API maintainer's point of view. Particularly, adding a new field or method to a final class is a backward-compatible operation. There is no risk of clash with a method or field added by the user of the API, because the user can't add anything to the class.

A particular example of a final class is an enum. It would thus appear that adding new fields to an enum is a backward-compatible operation. Or is it?

Let's assume the following common code where a switch statements walks over all fields of the enum:

switch (e) {
    case FIELD1:
        return "field1";
    case FIELD2:
        return "field2";
        assert false;

Ignore for the moment the fact that such code is better replaced with an instance method on the enum itself. Users tend to come up with creative ways to use your API, or could simply be working around the method missing from the API.

The assert false statement in the default branch is commonly used to ensure that all fields have been considered. However, if in the next version of the API FIELD3 is added to the enum, this code could suddenly start throwing an AssertionError. Code which worked fine in the previous version breaks down in the new version, although it compiles and links successfully. So, adding fields to a public enum is a semantically incompatible change.

I don't see a solution which would satisfy both the user and the provider of the API. Either the user doesn't assume that he knows which fields there are in the enum, or the provider freezes the enum once published. The latter seems to restrict the evolution of the API, so it is probably less practical. What do you think?

--AndreiBadea 14:08, 16 July 2008 (UTC)


Personal tools