The way I'm checking those arguments is rather tedious. Usually I'm using if/else statements to make sure everything is as expected. It's a manual process of syncing code and documentation, which is cursed to fail eventually.
Various people are suggesting you should use assertions to enforce design by contract. Assertions? I know, I know! In case you have forgotten, like me, or never heard of in the first place, here's what assertions are in the Java space:
An assertion is a statement in the Java programming language that enables you to test your assumptions about your program....The assertion statement has two forms...:
assert Expression1 ;
assert Expression1 : Expression2 ;
There are many situations where it is good to use assertions...:
- Internal Invariants
- Control-Flow Invariants
- Preconditions, Postconditions, and Class Invariants
Frankly, I have never used a single assert statement in production code. It always felt kinda uncomfortable to give up control to a single statement and I don't like the the fact that you can switch them off. If someone runs your code without -enableassertions and is not aware of asserts being used, they might observe strange behavior. Another thing that seems weird is the different opinions on the purpose of assert statements.
The simple assertion facility does enable a limited form of design-by-contract style programming. The assert statement is appropriate for nonpublic precondition, postcondition and class invariant checking. Public precondition checking should still be performed by checks inside methods that result in particular, documented exceptions, such as IllegalArgumentException and IllegalStateException.
Usually you don't want a "kind-of-design-by-contract" facility, which is only supposed to be used in parts of your code. First of all, you want to enforce contracts at an API level, which assertions are not intended to be used for. Second of all, if internal contracts are needed, I think you should use the same facility as in every other place of your code, in order to have a consistent way of getting things done. In my opinion it doesn't make sense to change your programming style and use assertions only internally. I'm always cautious when it comes to the performance of my code. The JVM can eliminate unnecessary if/else statements, but it seems to be a little different with disabled asserts in short running applications. In addition, performance is significantly degrading when running your code with assertions enabled, but to be fair, it looks like it's similar to an if/else statement approach. So if assertions are kinda broken and if/else statements are tedious and error prone, what's left? Maybe Annotations? A recent article on InfoQ, gives an overview of JSR-305:
JSR-305, led by FindBugs' creator Bill Pugh, is looking to create both a standard set of annotations that analysis tools can use, and a mechanism to allow developers to add additional annotations as they need to. The current proposal includes annotations for nullness, sign, language, and threading amongst others.
I think this sounds quite promising, especially the well defined mechanism to create your own annotations in addition to the standardized set. However, my feelings about annotations are ambivalent. I like them because they are easy to use and you get some kind of static typing with all its benefits. They also do a great job in documenting your code. I think one downside of annotations, though, is overuse. Almost every framework provides a set of annotations, mostly in replacement for XML configuration. If every class and method is annotated multiple times, your code will become virtually unreadable. Another thing that bothers me are 3rd party annotations. They are another dependency on your classpath, which need to be maintained. I think I'll stay with my error prone and tedious if/else statement technique. It'll do just fine for checking arguments of API methods - at least for now. However, JSR-305 might convince me to give up some control and let annotations take over assertion of arguments.