"I conclude that there are two ways of constructing a software design: One way is to make it so simple there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies."
I consider the Java Programming Language a mixed blessing. It is an industry standard language with a particularly good implementation. It is portable across multiple hardware architectures. Its popularity has resulted in lots of useful open source Java libraries and programming frameworks. These attributes make it a great choice to rapidly build reliable software on a large scale.
However, Java's sheer popularity also seems to have brain washed a generation of programmers into assuming that it is the best way to program. Java's well defined standard library, and the many excellent open source libraries available for different problem domains, are often mistaken as evidence of a superior programming language. This is a pity since Java is, at its core, a fairly primitive, statically typed, object oriented programming language. Besides making garbage collection an acceptable practice in industry, it has not moved language design or programming methodology much beyond what came before it.
In my experience the ubiquity of Java has resulted in a large number of programmers who have simply never actually learned to write good programs: they simply know how to string together pre-written plug and play code blocks or libraries (of which there are many)! I am astounded by how frequently these engineers have little of no understanding of how their code actually works! I would actually go so far as to claim that Java, and the teaching of it to beginning programmers, is actually producing programmers poorly equipped to do real software engineering.
These are of course very strong claims. After all there is undoubtedly a lot of high quality software that is written in Java! So it worth remembering that the critique I hope to develop here is not just about the language. All programming languages have some thing for every one to dislike. The critique here is really about how seductively Java has brain washed the unsuspecting programmer into unquestioningly accepting its limitations.
As with any attempt to criticise, we should be sure to really know the object of our criticism! I will suggest the following reading list as a minimum measure of an experienced Java programmer:
This is arguably the best book on the language. Read it carefully and keep it within easy reach. Until you understand every chapter and detail you should not claim to know the language. If you know it all and still find Java frustrating then remember to keep some perspective: you could be using something like C++ instead!
This is one of the finest books on design patterns. Design patterns are idea that has become the basis for teaching and talking about Object Oriented Programming. You must be familiar with the jargon introduced in this book since Java is unashamedly object oriented, and design patterns are a weapon in the Java programmers tool chest.
Obviously reading a set of books does not make a good programmer, but familiarity with the material in the list above is arguably a necessary foundation for a capable Java programmer.