Don't get me wrong. During my professional life I have written tons of Java code and of course I think it is a great language still. For sure it has been a great improvement from C++ and Smalltalk. But now even Java is starting to feel the weight of its 15 years.
Indeed during my experience I had to face up with some mistakes, flaws and lacks in its design and specification that made my Java programmer life less pleasant. With millions of Java programmers and billions of lines of code out in the world, I am far to say that Java is going to be dead in the near future. Anyway after the rise of some JVM compatible languages (my favorite is Scala), these issues are becoming even less tolerable and I am starting thinking that it is time to slowly move away from Java (but not from the JVM). More in detail, in my opinion, the 10 most important problems of the Java language are:
1. Lack of closure: I don't think I have to explain this. Functional programming exists since decades, but in the last years they are gaining more and more interests, mostly because it allows to write naturally parallelizable programs. I partially agree with Joshua Bloch that underlined the problems of introducing them in Java as a second thought (the BGGA proposal was truly awful), but anyway their lack makes impossible to have any kind of real functional programming in Java.
2. Lack of first class function: this issue is in some way related to the former one but I believe it is even worse. The only way to achieve a similar result in Java is by using the ugly and sadly famous one-method anonymous inner classes, but it looks actually a poor solution. Even in C# has been provided a better one by the implementation of the delegate mechanism.
3. Primitive types: it should be beautiful if everything in Java was an Object, but they didn't design it in that way. That leaded to some issue, like the impossibility to have a Collection of int partially resolved in Java 5 through the autoboxing feature (see below). It also generated some confusion between passing by value and passing by reference. Indeed a primitive data type is passed to a method by value (a copy of the data type is duplicated, and passed to the function) while true objects are passed by reference.
4. Autoboxing and autounboxing: this feature has been introduced in Java 5 to overcome the problems caused by the presence of primitive types. It allows to silently convert a primitive type in the corresponding object, but often it is cause of other problems. For example an Integer can have null value, but the same doesn't apply to int, so in this case when the Integer is changed in an int the JVM can't do anything else than throw a difficult to debug NullPointerException. Moreover it is cause of other strange behavior like in the following example where it is not so easy to understand why the test variable is false:
Intger a = new Integer(1024);
Intger b = new Integer(1024);
boolean test = a < b || a == b || a > b;
5. Lack of generics reification: generics are one of the cool features introduced with Java 5, but in order to mantain the compatibility with the older version of java they miss some important characteristic. In particular it is not possible to introspect their generic type at runtime. For example if you have a method that accepts as parameter a List<?> and you pass to it a List<String> you are not allowed to know at runtime the actual type of the generic. For the same reason you cannot create array of generics. It means that despite it looks quite natural the following statement won't compile:
List<String>[] listsOfStrings = new List<String>[3];
6. Unavoidable generics warnings: have you ever found yourself in the impossibility to get rid of a bothering warning about generics? If you make a large use of generics like me, I bet you did. And the fact that they felt the need to introduce a special annotation to manage this situation (@SuppressWarnings("unchecked")) is symptomatic of the dimension of this problem and, in my opinion, that generics could have been designed better.
7. Impossibility to pass a void to a method invocation: I admit that the need to pass a void to a method could look weird at a first glance. Anyway I like DSL and while implementing a special feature of my DSL library (lambdaj) I had the need to have a method with a simple signature like this: void doSomething(Object parameter) where the parameter passed to this method is the result of another method invocation done with the only purpose to register the invocation itself and execute it in the future. With my big surprise, and apparently without a good reason, since the println method returns void, I am not allowed to write something like this:
doSomething(System.out.println("test"));
8. No native proxy mechanism: proxy is a very powerful and widely used pattern, but Java offers a mechanism to proxy only interfaces and not concrete classes. This is why a library that provide this feature like cglib is employed in so many main stream frameworks like Spring and Hibernate. Moreover cglib implements this feature by creating at runtime a Class that extends the proxied one, so this approach has a well known limitation in the impossibility to extend and then proxy a final Class like String.
9. Poor switch ... case statement: the switch ... case as specified in java allows to switch only on int and (starting from java 5) enum. That looks extremely few powerful especially if compared with what offered by a more modern language like Scala.
10. Checked exception: like primitive types, checked exception have been one of the original sins of Java. They oblige programmers to do one of the following two equally horrible things: fill your code with tons of poorly readable and error prone try ... catch statement where often the most meaningful thing to do is to wrap the catched exception in a runtime one and rethrow it; or blurring your API with lots of throws clause making them less flexible and extensible.
The real problem here is that the only way to fix the biggest part of the issues I mentioned is to take a painful decision and define a specification of the language that drops the backward compatibility with the current one. I guess they will never do that, even if I believe it should not be extremely difficult to write a program that allows to automatically translate the old Java sources in order to make them compatible with this new hypothetic release. And in the end, this is the reason why I decided to start looking for a better JVM compatible language.
分享到:
相关推荐
42 Reasons To Start a Business Analyst Career
标题中的“10 reasons to use logback”是一个讨论日志框架选择的主题,它提出了使用logback而非其他日志工具(如log4j)的十个理由。logback是log4j的作者Ceki Gülcü创建的一个更现代、性能更优的日志框架。在...
Updating these books is usually not possible, for two reasons: (1) The copyright belongs to the author and/or publisher, either of whom may not allow it. (2) The source code for these books is often ...
On one hand, scientists do not always have the time to learn another programming language, especially if they are making a PhD, or doing something else which asks for a lot of time. Using direct and ...
- **Performance**: `HashMap` generally offers better performance than `Hashtable` due to the absence of synchronization overhead. #### 20. What is the main difference between ArrayList and Vector? *...
首先,关于理由#10,即使当前的采购程序能够接受的GMROI(General Merchandise Return on Investment,总体商品投资回报率)和库存周转次数,VMI仍有潜力带来进一步提升。VMI可以通过优化库存管理,减少过度库存和...
Starting with the basics of TDD and reasons why its adoption is beneficial, this book will take you from the first steps of TDD with Java until you are confident enough to embrace the practice in your...
Starting with the basics of TDD and reasons why its adoption is beneficial, this book will take you from the first steps of TDD with Java until you are confident enough to embrace the practice in your...
《XP:应对软件项目失败的10个原因》 在信息技术领域,软件开发项目的成功率一直是一个备受关注的话题。尤其在Windows XP的时代,软件工程的方法论正在经历着革命性的变革。Ian Mitchell在2001年的演讲中探讨了XP...
Chapter 10, Feature Toggles – Deploying Partially Done Features to Production, will show us how to develop a Fibonacci calculator and use feature toggles to hide functionalities that are not fully ...
`java.lang.UnsupportedOperationException`是Java中的一个运行时异常,它属于`RuntimeException`的子类。这个异常通常在尝试调用一个不支持的操作时抛出。在Java编程中,某些方法可能在特定对象或特定条件下不支持...
chm格式。。关于MAC的优点,参考资料
good suggestions on how to make this better, but I don't have the time to implement them myself. The code (/src/) is released as public domain, so you can do with it what you wish. The art (/res/) is...
Besides business reasons, we also use apps for leisure and for making our lives easier. The need for software development is not going away even with the newest AI advances. Someone needs to design ...
The Algorithms - Java ... There are many implementations of sorts in the Java standard library that are much better for performance reasons. Sort Algorithms Bubble From Wikipedia: Bubb
There is still considerable debate as to whether REST is better than SOAP (and vice versa), and perhaps there are still reasons to create SOAP services. While touching on SOAP, this document won't ...
10. **学术价值**:DLT作为研究工具,为学术界提供了丰富的探索方向。 综上所述,可分割负载理论在分布式计算领域展现出巨大的潜力和价值,不仅是理论研究的重要基石,也是实践应用的有力武器。随着技术的不断进步...