I used to use Java exclusively, until I was turned onto dynamic languages that just *make sense* logically. Most people are not programmers from birth, so in order to have programming appeal to them, you need to relate it to the real world, and show how they're in fact very similar, except with the computer interpreting it instead of your brain. While I believe it's important to show them how the computer is in fact involved, you shouldn't start people out with that part or their eyes will glaze over like a Thanksgiving ham. I hate people that think that this is a way of "weeding out the weak". Those people are arrogant are the reason that Revenge of the Nerds stereotypes are common among programmers.
Certain things appear as artificial barriers to programming. For instance, declaring the type of a variable when you define it:
Why must "variable" be a String? "variable" is simply a a name I'm giving to the string "Joe", but in real life, names don't really have any meaning outside of what they're actually naming. For instance, the term "my pet" can easily refer to any animal I might own, or even a rock, if I'm off my rocker. The astute OO programmer would then say, "But that means that the type of "my pet" would then be Ownable or some other abstract class like that." While true, most people don't think this way without some training first.
And voila, I have an (global) alias to my print function. But alas, Java does not treat functions as objects, thus not allowing me to do much at all without going into nasty reflection.
And that brings me to another problem with Java as a beginning language: its number of inconsistencies that can't be explained without going into nitty gritty details. Why can't I treat functions like any other object? Why is String capitalized and not int
? Why can't I use int
inside of generics? (Similary, why can't I use generics when declaring new arrays?)
The final straw for me is dealing with checked exceptions all the time. Rarely do I ever see the need for beginner programmers to handle exceptions gracefully. There are a lot of times when I am writing a more complex program and even I don't care about handling exceptions. In fact, many frameworks (including Spring and Hibernate, if I remember correctly) are getting to the point where they just throw subclasses of RuntimeException so the user doesn't have to use try/catch blocks unless they want to.
I could go on for another hour as to why Java is poorly designed for beginners (and a lot of experts... going back to Java hashtables after dynamic-language hashtables is like trying to itch your nose with a fishhook), but I'll spare you.
As for design patterns... they don't really apply just to Java... it's just that they're talked about more in Java than in most other languages currently. Java EE aims currently to fit a niche market ("Enterprise Applications") which is basically just a big design pattern to control access to a database. Rails is based on the same idea.