I think Rob Pike's observation Languages that try to disallow idiocy become themselves idiotic sums it up well. Languages are all about empowering developers and a language that strips away power from developers because they can be abused or misunderstood, is by definition less powerful.

It is assumed that this helps with the learning curve, take for example the old VB, very simple, easy to learn but lacks any form of power to do much past what is in the box.

Java took a road somewhere in the middle, not absolute power but not VB. Some people gripe about the choices they made because they are used to features of a more powerful language or features that are simpler in languages that don't religiously adhere to a functional/procedural/object oriented paradigm.

I do a bit of Java work, and as long as you stick to the constructs and patters it is not all that bad, but you do see the idiosyncrasy with the strict adherence to OO.

For example when I write an app in JavaScript I generally have my UI widgets which are OO, then I have procedural code that does the workflows and then I have functional code that provides reusable utility to the workflow. To emulate this in Java I have to create classes that represent the workflow, there are whole frameworks dedicated to doing this, such as Struts and it tends to take on a life of it's own, where my JavaScript work flow is just a JS file. In Java I have struts config, routing, classes that need to be inherited. It actually becomes very complex to undo the OO so I can use procedural code, that best fits work flow. Now that is just the workflow, to create utility functions I have to declare everything static and ensure that everything is self encapsulated for thread safety. Having to use OO to provide functional routines means double checking all the OO baggage to make sure I have not messed up scope and killed my thread safety. The alternative is to use OO for workflow and utility functions in which case the result is a mess of spaghetti code. Because OO does not lend itself to large multistage workflow. As well creating objects for utility functions is a lot of overhead.

Another example would be delegates, callbacks, anonymous functions, function pointers as they are called in other languages, their real name is Lambda Forms. Take for example in Lisp or JavaScript, I can take a reference to a function and pass it as an argument to another function. This provides all kinds of flexibility that allows for code reuse. For example say I have a routine that is exactly the same except for a small portion of code, with a Lambda Form type language I can create customized functions and pass them into the generic routine which then calls that custom logic. As well I can use it to give a routine access to limited scope outside of itself. It's actually really powerful and can eliminate a lot of code. In strict strong typed OO without access to pointers though it is a convoluted process to accomplish this simple language construct. You have to use an interface that defines a function signature and then you have to inline declare a class that implements that interface, from there you can give it scope to the encapsulating class. Again, the dogmatic adherence to Java's language structure and rules creates something that is far more complex that simple Lambda Forms.

Multiple inheritance is a big issue for many, a very powerful feature was thrown out due to the fact that in a few fringe cases you run into conflicts, when a simple chain of command would have sufficed. A lot of OO's promise went out the window when multiple inheritance was killed in Java. For example say I have an object and I want it to serialize to a file with MI, I could inherited a parent object and a file serialize and with little code, create such an object. With single inheritance I am left with stripped down interfaces that I have to go and write the code for, they do nothing but guarantee a contract. This is great for a bunch of custom classes that need to be treated generically, but for cases where I want to take two novel classes and create a class as a product of them, it fails. Ruby and some of the JavaScript toolkits like Dojo did a really good job of addressing the issues of multiple inheritance via mixins. They addressed the issues without throwing it out and are the better for it.

Finally, I really would like to see a languages that uses the idea Microsoft used in C# with the unsafe flag, but a little different, instead of having to declare something unsafe in code, have a layered approach to the language for example first layer is dynamic with no type safety, maybe not even OO at that layer, kind of like basic or JavaScript. Just a simple language that can be picked up by complete novices. Then you can choose to implement addition layers like type safety, OO. Then at another level you can chose to layer on Lambda's pointers, multiple inheritance. etc. The really nice part about this would be that you could turn off layers when they are getting in the way of doing something simple, like say needed to drop out of the OO box for a simple routine.

As a note: I do a lot of Java development and have worked with most of the major languages, as a language I don't find Java all that bad, and I find the wealth of libraries available generally far outweighs any idiosyncrasy the language brings as baggage with it.