You will have the fewest development problems and the most reliable programs by using Java's features and programming methodologies that cause your program to fail when there is a problem, and to fail as soon as possible.
You will write a lot of bugs. Just accept it, but make it as easy as possible to find them.. I've known a lot of fanatically capable programmers, but only one who wrote essentially flawless code in the first draft (Ira Rubin).
Ideally, you want someone else to find your errors. Compiler error checking is your friend because it finds errors you've made immediately and tells you about them. Some development systems use continuous compilation, which informs you about problems as you type with jagged red lines appearing under your errors.
The quality of compile-time error diagnosis is a function of both language and compiler design. The basic Sun javac compiler that many development systems use gives relatively poor error diagnostics. On the other hand, the language design has many helpful features, and more are being added. Java's strong typing (variable types must be declared), required casting are good features, asserts, and exceptions all help produce correct code. Java 5 has further further improved reliability with generics (templates), type-safe enums, and a "foreach" statement. The goal of not allowing illegal programs to compile is impossible, but its interesting to think of how the language design could be improved to help prevent or detect errors at compile time.
The worst kind of runtime error causes the program to slowly fall apart. Perhaps the greatest leap that Java made over C++ is providing runtime checks for common errors such as array indexes out of bounds and storage management, especially automatic garbage collection.
Yet, there are still many possible run-time errors.
Java provides another great tool in the
statement which checks that things that must be true really are
(See Assertions). Learn about assertions and
While it is true that testing can only show the
presence of bugs, not their absence, it essential.
Methodologies such as Extreme Programming
require that test data be written before the
JUnit testing facility makes
writing and running tests much easier. With fast machines
it is possible to run regression tests frequently.
You will write bugs and you want them caught as early as possible. Use types to help catch errors at compile time if possible; use assertions to stop execution if something is wrong; use rigorous testing to find errors.