Soviet tanks were not exactly 'state of the art' either, but they worked pretty good. What's 'hot' doesn't automatically qualify to solve things for the longer term, in fact being 'hot' is a fantastic reason to stay clear of a technology, because if it is in fashion this year it could very well be out of fashion next year.
Yeah, except many of these ideas have been production-tested for 25+ years.
Remember that Java is the language that introduced garbage collection to the world. Before Java, it was basically an untested academic thing that Lisp machines did. Why be liberal with such a radical new idea and conservative with things that let you implement programs the same way you do now but with less typing? It makes very little sense.
Not to mention that I have never said a thing about things like "public static void". I specifically mentioned the object system above and how much manual easy-to-get-wrong code is required simply to make things that have an equals method also have a "not equals" method.
Sometimes I wonder why I bother arguing with axod. Wait, I always wonder that...
Come on. How often do you really need an equals method in your classes? It's not a big deal. (No, I'm not one of those people who insist on writing equals/hashcode/toString on everything even when it's not being used).
I wonder why I try to bring sanity to these sorts of discussions also :/
Since Java lacks generics, there are many kinds of code which require duplicate code in Java. Specifically, every place where you would use generics in another language (Templates in C++, or TypeClasses in Haskell, for instance).
Java definitely supports generics as of 1.5 - did you mean that it doesn't support generics to the extent of C++? Most basic uses (containers) are identical between the languages, and while Java doesn't allow compile-time "duck typing" that C++ does, you can fake it by using the "? extends SomeInterface" syntax.
Java supports type erasure, which it idiosyncratically calls "generics", even though it does not allow generic programming. A generic function in a language with actual generics can work generically, on more than one type. A "generic" function in Java can work on exactly one type, namely the type which the "generic" type becomes after type erasure.
You can use "? extends SomeInterface" only if you write SomeInterface wrappers for every type which you want to use "generically." This is boilerplate relative to most other languages.
Personally, I find this boilerplate equivalent to the comments one has to write documenting the requirements of the type, with the added benefit of readable error messages when you pass the wrong type. In other words, I find:
// T here is a type that must support these two operations:
// bool froznit();
// void frobnob(Foo* foo);
template <class T> class Frozner { ... }
And
public interface SomeStupidName {
public bool froznit();
public void frobnob(Foo foo);
}
public class Frozner<? extends SomeStupidName> { ... }
I think that has to do a lot with Java's heritage.
What they were shooting for seems to have been something that combines the syntax of C and some of C++ for easy access to a large pool of existing programmers but without those 'scary pointers', and the memory leak issues associated with bad programming habits in C and C++.