evolving_java-based_apis
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| evolving_java-based_apis [2014/02/06 07:19] – yann | evolving_java-based_apis [2025/01/15 21:40] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 22: | Line 22: | ||
| * a Component can offer an API and its implementation, | * a Component can offer an API and its implementation, | ||
| * a Component can offer a " | * a Component can offer a " | ||
| - | and the question is "For roles played by Clients, would the [...] API change render invalid a hypothetical Client making legal usage of the existing API?" The document then provides a table (augmented here with the addition of API methods to assess the contract compatibility of a change: | + | and the question is "For roles played by Clients, would the [...] API change render invalid a hypothetical Client making legal usage of the existing API?" The document then provides |
| - | ^ Types of Changes ^^ Roles ^^ | + | ^ |
| - | | Method preconditions | Strengthen | Breaks compatibility for callers | Contract compatible for implementors | | + | | Method preconditions |
| - | | | Weaken | + | | ::: | Weaken |
| + | | Method postconditions | Strengthen | Contract compatible for callers | ||
| + | | ::: | Weaken | ||
| + | | Field invariants | ||
| + | | ::: | Weaken | ||
| + | | Adding an API method: | ||
| + | | - To an interface | ||
| + | | - To a class((Intended to be sub-classed by implementors)) || Contract compatible for callers | ||
| + | | - To a class((Not to be sub-classed by implementors)) | ||
| - | Method postconditions Strengthen Contract | + | Then, the document goes on enumerating, |
| - | Weaken Breaks | + | * API packages; |
| - | Field invariants Strengthen Contract compatible for getters Breaks | + | * API interfaces (methods, fields, and type members); |
| - | Weaken Breaks | + | * API classes (methods and constructors, |
| + | |||
| + | The document also discusses annotations on API constituents, | ||
| + | |||
| + | Finally, the document includes several suggestions to design better API or make it easier to change them: | ||
| + | * Clients must only use published (not internal), API (even if other constituents are public); | ||
| + | * " | ||
| + | * "[A]ll gender changes involving classes, enums, interfaces, and annotation types break binary | ||
| + | * "[A] pre-existing Client subclass of an existing implementation might still provide a pre-existing implementation [of a newly added method, by sheer luck]"; | ||
| + | * "API interfaces that Clients should implement should not include fields", | ||
| + | * " | ||
| + | * "API classes should always explicitly declare at least one constructor"; | ||
| + | * " | ||
| + | * " | ||
| + | * "Java compiler always inline the value[s] of constant fields [...] this does not meet the objective of changing the API field' | ||
| + | * "As long as the erasure looks like the corresponding declaration prior to generification, | ||
| + | * " | ||
| + | * "[T]ag all stored data with its format version number"; | ||
| + | * " | ||
| + | |||
| + | Also, the document provides the simplest, clearest explanation of Java 1.5+ type erasure mechanism, that I reproduce here for the sake of beauty: | ||
| + | |||
| + | >> A raw type is a use of a generic type without the normal type arguments. For example, " | ||
| + | >> | ||
| + | >> The term erasure is suggestive. Imagine going through your code and literally erasing the type parameters from the generic type declaration (e.g., erasing the "< | ||
evolving_java-based_apis.1391671177.txt.gz · Last modified: (external edit)
