User Tools

Site Tools


evolving_java-based_apis

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
evolving_java-based_apis [2014/02/06 07:24]
yann
evolving_java-based_apis [2019/10/06 20:37] (current)
Line 22: Line 22:
   * a Component can offer an API and its implementation,​ it is the implementor;​ the Client access the API, it is the caller;   * a Component can offer an API and its implementation,​ it is the implementor;​ the Client access the API, it is the caller;
   * a Component can offer a "​callback"​ API, it is the caller; the Client must implement the API, it is the implementaor.   * a Component can offer a "​callback"​ API, it is the caller; the Client must implement the API, it is the implementaor.
-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 ​[[http://​wiki.eclipse.org/​Evolving_Java-based_APIs|a table]] (augmented here with the addition of API methods to assess the contract compatibility of a change:
  
-^   Types of Changes ​  ​^^   ​Roles ​  ^^+^   Types of Changes ​   ^^   ​Roles ​  ^^
 | Method preconditions ​ | Strengthen | Breaks compatibility for callers | Contract compatible for implementors ​ | | Method preconditions ​ | Strengthen | Breaks compatibility for callers | Contract compatible for implementors ​ |
 | :::                   | Weaken ​    | Contract compatible for callers ​ | Breaks compatibility for implementors | | :::                   | Weaken ​    | Contract compatible for callers ​ | Breaks compatibility for implementors |
Line 31: Line 31:
 | Field invariants ​     | Strengthen | Contract compatible for getters ​ | Breaks compatibility for setters ​     | | Field invariants ​     | Strengthen | Contract compatible for getters ​ | Breaks compatibility for setters ​     |
 | :::                   | Weaken ​    | Breaks compatibility for getters | Contract compatible for setters ​      | | :::                   | Weaken ​    | Breaks compatibility for getters | Contract compatible for setters ​      |
-| Adding an API method ​             ||                                                                         ​|| +| Adding an API method:                                                                                      ​|||| 
-  * To an interface ​              ​|| Contract compatible for callers ​ | Breaks compatibility for implementors |+To an interface ​                                         || Contract compatible for callers ​ | Breaks compatibility for implementors | 
 +| - To a class((Intended to be sub-classed by implementors)) || Contract compatible for callers ​ | Breaks compatibility for implementors | 
 +| - To a class((Not to be sub-classed by implementors)) ​     || Contract compatible for callers ​ | Contract compatible for callers | 
 + 
 +Then, the document goes on enumerating,​ for each possible types of changes to API-related constituents of a Component, which ones are binary compatible and which ones are not, see the [[http://​wiki.eclipse.org/​Evolving_Java-based_APIs_2|original document]] for exhaustive lists. The API-related constituents include: 
 +  * API packages; 
 +  * API interfaces (methods, fields, and type members); 
 +  * API classes (methods and constructors,​ fields, type members). 
 + 
 +The document also discusses annotations on API constituents,​ turning non-generic types into generic ones, and Java reflection. Regarding reflection, it emphasises that "[n]o additional provision are made for clients that access the API using Java reflection"​. It also explains that most reflection APIs are safe, except Class.getDeclaredXXX(...) methods, because they are "​dependent on the exact location of [a constituent] and include non-public [constituents] as well as public ones"​. 
 + 
 +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); 
 +  * "​[O]bsolete API elements are notoriously difficult to get rid of"; 
 +  * "[A]ll gender changes involving classes, enums, interfaces, and annotation types break binary compatibility [...]";​ 
 +  * "[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",​ which is not always possible because enumeration constants used in switch statements;​ 
 +  * "​[A]dding type parameters to a previously unparameterised type retains compatibility";​ 
 +  * "API classes should always explicitly declare at least one constructor";​ 
 +  * "​Client code can use the values() method to determine the ordinal positions of enums constants";​ 
 +  * "​Adding and deleting checked exceptions declared as thrown by an API method does not break binary compatibility;​ however, it breaks contract compatibility (and source code compatibility)";​ 
 +  * "Java compiler always inline the value[s] of constant fields [...] this does not meet the objective of changing the API field'​s value";​ 
 +  * "As long as the erasure looks like the corresponding declaration prior to generification,​ the change is binary compatible with existing code";​ 
 +  * "​[G]enerifying an existing API is something that should be considered from the perspective of the API as a whole rather than piecemeal on a method-by-method or class-by-class basis";​ 
 +  * "[T]ag all stored data with its format version number";​ 
 +  * "​Deprecate and forward"​ and-or "Start over in a new package"​ and-or [[http://​www.mif.vu.lt/​~plukas/​resources/​Extension%20Objects/​ExtensionObjectsPattern%20Gamma96.pdf|"​COM style"​]] and-or "​Mak[e] obsolete hook method final"​. 
 + 
 +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, "​List"​ in the declaration statement "List x = null;" is a raw type since List is a generic type declared "​public interface List<​E>​ ..." in JDK 1.5. Contrast this to a normal use of List which looks like "​List<​String>​ x = null;" or "​List<?>​ x = null;" where a type augument ("​String"​) or wildcard is specified.  
 +>>  
 +>> 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 "<​E>"​ in "​public interface List<​E>​ ...") to get a non-generic type declaration,​ and replacing all occurrence of the deleted type variable with Object. For type parameters with type bounds (e.g., "<E extends T1 & T2 & T3 & ...>"​),​ the leftmost type bound ("​T1"​),​ rather than Object, is substituted for the type variable. The resulting declaration is known as the erasure."​
evolving_java-based_apis.1391671492.txt.gz · Last modified: 2019/10/06 20:37 (external edit)