Java, by and large is a mess. The applications and the need for java systems is not a mess. At least for the time being there is still going to be a need for java applications and developers. With that being said, there are a couple of steps that can be taken to ensure a robust system with a limited number of bugs if you abide by a couple of rules and don't get caught in some java development traps. I don't go over the most obvious ones but I have gotten interested (again) into Contract oriented programming. Contract oriented programming, design by contract; ensures a true object oriented model, allows for better testing. Here is a quote from an Eiffel document, "In human affairs, contracts are written between two parties when one of them (the supplier) performs some task for the other (the client). Each party expects some benefits from the contract, and accepts some obligations in return". Basically, with design by contract, you limit the number of side-effects that can occurr when an operation is invoked. When call a method, passing a message, you want that result to return the value you would expect. If the method returns a String, you want it to return a string. Not a generic Object or Numeric. If you have a List of elements, and there are 5 elements in that list and you expect 5 elements returned. You want a list with 5 elements.
Tony Morris, a former(?) Java developer is very fluent in the ways of Design by Contract; he created the ContractualJ framework and had this to say:
"ContractualJ is an open source project that is aimed at providing a robust API specification for the Java programming language. The ContractualJ API Specification is independent of any given context, except that it either replaces an existing core J2SE API Specification that is poorly designed, or adds a feature that does not exist in the core API. ContractualJ serves as an example of writing software using Contractual Oriented Programming, while also highlighting the flaws of the dependent tools (e.g. Java) and exemplifying the optimal workaround to the existence of these flaws. "
Here are some more quotes from Tony and as of now I don't have much to say on the subject.
"1) Interfaces define a contract for *how a class may be accessed*, but don't provide ANY information about what the class does, or how it does it.
2) Abstract classes allow (among other things) *commonly implemented processes to be encapsulated"
* All classes are declared final. Concrete behaviour inheritance is not permitted.
* All local variables and fields are declared final, unless otherwise required not to be by the context. A local variable or field that is assigned once must be declared final.