别误解,其实在我的职业生涯中,我已经编写了无数的Java代码;而且,我仍然认为Java一门伟大的(程序)语言。相对于C++和Smalltack,Java已经有了很大的改进;但现在,即使是Java,也已经开始感觉到了其15年的积重。
事实上,在我的经历中,我总是不得不面对Java的设计和规范上的一些错误、缺陷和不足,这些东西,让我的Java程序员生活少有乐趣可言。现在全世界的Java程序员有数百万之众,Java写就的代码更达数亿行,要是我说Java在不久的将来死去,这还有些远。不管怎样,随着一些兼容JVM的语言出现(我最钟意Scala)后,这些问题变得越发不能容忍了,我开始想,是时候慢慢离开Java了(但并不脱离JVM)。具体说来,我认为Java语言的10大问题是:
1、缺少闭包(closure):我想这个不需要解释了。函数式编程已经存在几十年了,但最近几年,它们获得了越来越多的关注,最主要的原因,是它可以自然地编写并行程序。我部分的同意Joshua Bloch强调在Java中引入闭包的问题需要再想一想(BGGA提议的方式真的很糟),至少闭包的缺失,使得在Java中做任何真正的函数式编程都是不可能的。
2、缺少一等函数:这个问题与前一个有些关联,但我认为它更糟糕。在Java里,要达到类似效果的唯一方式,是使用著名的、丑陋悲惨的单方法匿名内部类,但这看上去的确是一个拙劣的方法。甚至在C#中,也通过代理机制,提供了一个更好的实现。
3、原生类型(Primitive types):如果在Java中一切皆对象,那是多么完美啊,但他们偏偏不这样设计。因而,这一点导致了一些问题,比如,不能把一个int放到集合(Collection)里,这个在Java5中通过自动装箱特性得到了解决(下面会提到)。它也造成了传值与传引用上的困扰,原生类型数据是通过值传给方法的(复制一份拷贝,然后传给函数),而真正的对象是通过传递(译注:其实是复制对象地址再传递,因此应该也是传值方式,只是由于函数内部可通过这个对象地址访问对象,因此效果上类似传引用)。
4、自动装箱(Autoboxing)和自动拆箱(autounboxing):这个特性是为了解决因原生类型的存在所导致的问题,在Java5引入的。它允许静默地转换原生类型到相应的对象,但这常常导致其它的问题。比如Integer可以为null,但int不能,因此这时JVM只能抛出一个难以调试的空指针异常(NullPointerException)。此外,它还可能导致其它奇怪的行为,就像下面的例子,我们就很难理解,变量test为什么是false:
Intger a = new Integer(1024); Intger b = new Integer(1024); boolean test = a < b || a == b || a > b; |
5、缺少范型具类化:范型是Java5引入的一个很酷的特征,但是为了保持与旧版本Java的兼容性,导致缺失某些重要的特性,尤其是不能在运行时反省范型的类型。例如,你有一个方法,接受List<?>参数,如果传进来一个List<String>,你却不能知道运行里该范型的确切类型。同理,你也不能创建范型数组。这意味着,尽管下面的代码看起来很自然,但却不编译不了:
6、不可避免的范型警告:你有发现过自己陷入不可能去掉的关于范型的警告么?如果你像我一样大量使用范型,我打赌你碰到过。事实上,是这个问题的规模化症状,让他们认为需要引入一个特定的注解 (@SuppressWarnings("unchecked")) 来处理这种情况,我觉得,范型应该可能被设计的更好。
7、不能传void给方法调用:我得承认,这种给方法传递void的需求,乍一看有些怪异。我喜欢DSL,当我实现自己的DSL库(lambdaj)的一个特定特性时,我不得不需要一个方法声明成这样的签名:void doSomething(Object parameter),这里为这个方法传进来的参数parameter,是另一个方法调用的结果,它唯一的目的,是注册调用(的对象)自身,以可以在以后执行它。让我吃惊的是,即使println方法返回void,看上去也并没有一个好理由,不允许我把代码写成这样,:
doSomething(System.out.println("test"));
8、没有原生的代理机制:代理是一种非常有效和应用广泛的模式,但Java提供的代理机制,只针对接口,而不是具体类。这是为什么象cblib这样提供这种机制的库,被如此多的主流框架,如Spring和Hibernate,采用的原因。此外,由于cglib通过运行时创建被代理类的子类来实现的,因此这些种方式有一个众所周知的限制——不能代理final类,比如String.
9、差劲的Switch……case语句:Java规定,switch……case只能选择int和enum(Java5开始)。这一点如果跟更现代的语言如Scala相比,看起来简直太弱了。
10、受检查异常(Checked exception):类似原生类型,受检查异常也已经成为Java的一个罪孽之源。它迫使程序员必须做下面两件极其糟糕讨厌的事情中的一个:让你的代码里充斥大量的、糟糕难读的、容易出错的try……catch语句,而这样做的最大意义,只是将捕获的异常,包装成运行时异常,然后再重新抛出;或者是让大量的抛出声明子句污染你的API,让接口缺少灵活性和可扩展性。
真正的问题是,这里我提到的这几大主要问题,唯一的解决办法,是要做一个痛苦的决择,定义一套新的语言规范,放下当前版本的向后兼容性。我猜他们永远也不会这么做,虽然我相信,如果编写一个能够自动转换旧Java源码的程序,让它们与假设的新版本兼容,并不是很困难。最后,这就是我决定开始寻找一个更好的JVM兼容语言的原因。
相关推荐
**基于Java语言十大经典排序算法** 排序算法是计算机科学中不可或缺的一部分,特别是在数据处理和算法设计领域。在Java编程中,理解并掌握各种排序算法能够帮助开发者提高代码效率,优化性能。以下是Java语言中十大...
以下是针对Java语言常见的十大误解的详细解析: 1. **误解一:Java是HTML的扩展** Java并非HTML的扩展,而是独立的编程语言,专门用于构建应用程序。HTML主要用于描述网页结构,而Java可以嵌入到网页中以创建交互...
以上每个案例都是Java编程中的重要组成部分,通过这些案例的学习,初学者不仅可以巩固基础,还能提升解决问题的能力。同时,这些案例也可以作为进阶学习的起点,进一步探索Java的高级特性,如并发编程、JVM优化、...
Java作为一门广泛使用的编程语言,其经典案例是学习和理解其特性和应用的重要途径。"Java十大经典案例"由张恒汝编著,通过科学出版社发行,旨在为学习者提供丰富的实践素材,深入理解Java的强大功能。以下是这些案例...
在Java编程语言的世界里,经典的案例是学习和理解其核心...通过这些案例,开发者不仅可以增强对Java语言的理解,还能提升解决实际问题的能力。在学习过程中,建议动手实践,结合源代码分析,以便更好地掌握这些知识点。
Java语言是一种广泛应用于现代软件开发的高级编程语言,由James Gosling领导的团队在1991年开发,最初命名为Oak。随着互联网的迅速发展,Java在1995年正式发布,因其跨平台的特性及优秀的技术表现,被PC Magazine...
参与社区不仅能解决技术问题,也能提升自己的编程技巧和设计理念。 总结来说,"JAVA十大经典手机游戏"是一个极好的学习资源,它不仅提供了实际的编程示例,还揭示了JavaME在手机游戏开发中的应用和挑战。对于想要...
通过深入研究这些案例,读者不仅可以掌握Java语言的核心概念,还能提升解决实际问题的能力。每个案例都是一次宝贵的实践经验,将理论知识转化为实际编码能力。通过实际运行和调试代码,学习者能够更深刻地理解Java...
Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。本教程涵盖了从基础到高级,再到数据结构和算法的全面Java知识体系,旨在帮助开发者深入理解和掌握这门语言。 首先,我们从“Java基础”...
然而,要充分利用网络计算模式的功能与效益,平台的运行环境是个制约因素,而Java语言和Java技术则是解决这一问题的最佳途径。 1991年,SUN公司的Jame Gosling、Bill Joe等人试图为电视、烤箱等家用电器开发一种...
通过实践,你可以深入了解Java语言的特性和使用场景。 2. **Spring框架案例**:Spring是企业级Java应用开发中最常用的框架之一,它提供了依赖注入、AOP(面向切面编程)、事务管理等功能。案例可能包括创建简单的...
### 提高Java水平的十大技术 在IT领域,特别是软件开发行业中,Java作为一种广泛应用的编程语言,其重要性不言而喻。对于希望从初学者成长为高手的Java开发者而言,掌握一系列关键技术和概念是必不可少的。本文将...
Java是世界上最流行的编程语言之一,尤其对于初学者和专业开发者来说,掌握其核心概念和常见问题的解决方法至关重要。"Java十大经典例题"是一份针对Java学习者的宝贵资源,它包含了广泛应用于实际开发中的典型问题和...
掌握这些语言不仅能帮助开发者更好地理解不同编程范式的差异,还能提高解决复杂问题的能力。 #### 五、JavaScript 尽管名称相似,但JavaScript与Java没有直接关联。JavaScript是一种客户端脚本语言,主要用于Web...
Java作为一门广泛使用的编程语言,其中高级面试题往往涵盖了多方面的知识点,旨在考察候选人的技术深度和广度。以下是对这些面试题的详细解析: 1. **内存管理与垃圾回收** - Java的内存分为堆内存(Heap)和栈...