C4J uses the
of Java and extends it to interfaces and inheritance
by separating the assertions in separate contract classes.
As contract classes are plain Java classes,
software engineers have the full power of Java to express even complicated assertions.
Furthermore contract classes are stateful,
as each instance of a protected class has its own instance of its protecting contract class.
Based on that simple and powerful concept C4J supports:
- Class invariants.
- Postconditions, with access to return- and old-values.
- Access to the public members of the guarded class from the contract implementation.
- Annotations like @Pure to explicitly mark methods as "pure" (even methods defined in interfaces).
- Automatic validation of pure methods, i.e. automatic checking that as pure annotated methods really do not have any side effects.
- Access to the "old" values of target attributes in postconditions.
- Simple to use "unchanged" check in postconditions to ensure that a target attribute has not been changed by the method execution.
- Contracts for interfaces, i.e. define a contract for an interface and all implementing classes (and their sub classes) will verify the contract.
- Inheritance of contracts, i.e. extending classes or implementing interfaces inherits the parent's contracts, also for overridden methods.
- Contracts for abstract methods, i.e. define a contract for an abstract method in an abstract class
and all implementing classes (and their subclasses) will verify the contract.
- External contracts allowing to attach contracts to legacy code.
- Combinations of "internal" and "external" contracts in the same project.
- Combinations of "interface contracts" and "class contracts", works like contract refinement.
- Contract refinement, i.e. extending classes may define their own contracts
in which case they are merged with the parent contracts
according to the
Liskov substitution principle.
- Logging of contract validations.
- Ability to configure which contracts should be activated and which not.
- Ability to configure how to react to a contract violation, i.e. throwing an assertion error and stop the application
or just logging the contract violation and continue the execution of the application.
- Possibility to debug contracts in your favorite IDE.
- Writing contract classes using your favourite IDE's code completion features.
- Refactoring and other
Agile Software Engineering (ASE)
techniques necessary in Scrum development teams.