别误会我. 在我的职业生涯中我写了无数的Java代码,我当然认为它是个十分优秀的语言. 必须承认,Java在C++和Smalltalk的基础上改进了不少. 但是现在,Java也开始感觉到了第15岁的沉重了.
确实,在我的编程日子中,我不得不面对Java在当初设计时留下来的错误,缺陷和限制.这给程序员的编程生活减少了很多乐趣.
面对成百万的Java程序员和他们产出的亿计的代码行,我恐怕必须要说:Java在不久的将来就会死掉.
然而,随着越来越多的JVM兼容的语言的出现(我最喜欢的是Scala),这些问题让我越发没有耐性,我认为是到了慢慢脱离Java的时候了(但不脱离
JVM). 详细的说,按我的观点,Java的十大问题是:
1.没有Closure:
我
觉得没必要再次解释这个问题. 基于函数的编程十年前就出现了,但这几年越来越受人们的关注.最主要的原因是它能让人按最普素的方式编写并行程序.
Joshua Bloch
强调应该再考虑把这个特征加入到Java中(BGGA的野心有些大)我对这些观点有所保留.事实上,他们的设计上的缺陷不可能使Java具有真正的函数
性.
2.没有一级函数:
这个问题跟前一个问题有关联,但我觉得这个问更糟糕 . 在Java里实现类似功能的唯一途径是使用巨丑陋,巨郁闷的只有一个方法的内部匿名类,这个方案实在很差劲. 就连C#也通过代理机制提供了一种比它好的实现.
3. 基本类型:
如果Java里的一切都是对象,那将是一个很美的事情,但Java并没有像这样设计。
这就导致了一些问题,例如,你不能实现一个装着int的Collection,Java5里使用自动封装机制只是部分的解决了这个问题(如下).
它也同时产生了按值传参和按引用传参的混淆. 基本数据类型是通过值传递的(把数据复制一份传近去),而真正的对象是按引用传递的.
4.自动封装和解封:
这
个特征已经引入到Java5里了,用来解决由于基本数据类型的存在而产生的问题.
它可以隐式的自动将基本数据类型转化为相应的对象,但这经常会引起一些问题.
例如一个Integer可以是null值,但是int却不可以,所以当你把这样一个Integer被转化成int时,JVM除了能抛出该摸不着头脑的
NullPointerException,什么都做不了。
更甚者它能产生一些其他的奇怪的行为,就像下面的,估计大家都会很难理解为什么这个给变量会是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>时,你却不能即时知道确切的参数的类型。 同样的道理,你不能创建一个数组型的泛型。
这就意味着下面这行尽管看起来是如此自然无误的语句去不能编译:
List<String>[] listsOfStrings = new List<String>[3];
6.逃避不了的泛型警告:
你
是否曾经发现自己怎么都去不掉那些关于泛型的警告? 如果你像我一样大量的使用泛型,我相信你会的。
就连Java设计者们也感觉到有必要引入一个特殊的标记
(@SuppressWarnings("unchecked"))来解决这个问题,这正表明这个问题的严重性,按我的观点,泛型实际上可以设计的更好。
7.不能在调用方法时传入一个 void:
我相信把一个void 传进一个方法的需求初一看时是多么的奇怪。 问题是这样,我喜欢DSL,为了在我的DSL库里(lambdaj
)
实现一个特殊的功能,我需要写这样的一个方法: void doSomething(Object
parameter),被传进去的参数有可能是另一个可以被调用的方法语句,这个语句将来将会被执行。
让我十分沮丧的是,很显然,没有什么好方法,因为,就像下面,这个println方法会返回void,Java是不允许我写成这样的:
doSomething(System.out.println("test"));
8.没有本地代理机制:
代
理是一个很有用的且广泛使用的模式,但是Java提供的代理机制只是使用接口来实现,没有具体的类。
这就是为什么像cglib这样能提供这种功能的类库会在如此多的像hibernate,spring的主流框架中使用.
然而cglib只是通过即时生成一个类来继承扩展被代理的对象的方法实现这个特性.这种方法有个明显的限制,就是你不能生成一个对象继承一个final对
象,spring里就有这个问题.
9.弱的
switch ... case语句:
switch ... case在Java里规定的只能使用int和enum(enum在Java5里才开始用)。 这个让人觉得特别的无奈,特别是跟那些提供了这个功能现代语言来说,例如scala.
10.异常检测:
就
像基本数据类型一样,异常检测是Java的原罪之一。
它强迫程序员去做下面两个让人哭笑不得的事情之一:一个是让你把代码里填满不可理解又易出错的try ...
catch语句,这样做唯一的目的就是把运行时捕捉到的异常再抛出去;或者是把你的API上加入成堆的throws语句,使程序缺少灵活性而且不易扩展。
能解决大部分上面我所提到的这些问题的唯一方法是,需要做一个痛苦的决定,定一个新的语言规范,抛弃向后兼容的做法,从头再来。
我相信,他们永远不会做这个事情,即使是我相信,写一个能自动转化老的Java源代码,达到兼容目的的工具并不困难的情况下,他们也不愿意做。
最终,这就成了我为什么要开始去寻找一个更好的JVM兼容的编程语言的理由。
外刊IT评论
分享到:
相关推荐
本文将详细介绍一系列针对不同层次学习者的Java学习网站及论坛,帮助读者更好地掌握这门语言。 ### 一、官方与权威学习资源 #### IBM DeveloperWorks - **网址**: <http://www-900.ibm.com/developerWorks/cn/...
在实际开发中,了解如何使用反编译器可以帮助我们更好地理解依赖的库,学习他人的实现技巧,以及在没有源代码的情况下进行问题排查。然而,由于其潜在的风险和限制,使用反编译器应谨慎且遵守相关法律法规。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 20、abstract class和interface有什么区别? ...
68. 非名校背景:强调实际能力比学历更重要,分享你的成就和技能。 69. 学历与能力:强调实际工作能力和潜力,而非仅仅依赖学历。 通过以上回答,你可以展示出一个全面而专业的形象,增加面试成功的几率。在面试...
- **特色**:该论坛提供了丰富的管理经验和案例分享,帮助IT管理者更好地规划和发展企业信息化策略。 - **推荐理由**:对于希望提升自己管理水平的IT人士来说,这里是一个很好的学习平台。 #### 10. AmTeam论坛 ...
和智慧,让你能够真正掌握接口或抽象类的应用,从而在原来的 Java 语言基础上跃进一步,更重要的是,GoF 的设计模式反复 向你强调一个宗旨:要让你的程序尽可能的可重用。 这其实在向一个极限挑战:软件需求变幻...
- 讨论了经典书籍《Effective Java》第二版中文翻译的术语选择,以促进中文读者更好地理解和应用书中的编程原则。 14. **AOP缓存再讨论** - 面向切面编程(AOP)中的缓存机制是提高性能的重要手段,讨论可能涉及...
### 面试常见人事回答问题详解 #### 一、自我介绍 **问题:** “请你自我介绍一下” **解析:** 自我介绍通常是面试的第一个环节,它不仅能够让面试官对您...希望以上的解析能够帮助您更好地准备面试,祝您面试成功!
在Android开发领域,有时我们需要对APK文件进行逆向工程,以分析其内部结构、查看源代码或修改功能。...通过理解这些工具的工作原理和使用方法,开发者可以更好地应对各种挑战,同时也需时刻关注知识产权的合规性。
我们没有理由让每⼀个⼈在家都拥有⼀台电脑。这句话强调了计算机的普及,计算机可以普及到每个家庭和个人。 知识点43: C++的特点 在C++⾥你想搬起⽯头砸⾃⼰的脚更为困难了,不过⼀旦你真的做了,整条腿都要报销。...
例如,它可以帮助开发者更好地管理数据库查询、API调用或第三方库的依赖,使得整个系统的架构更加清晰和高效。 总的来说,Refke作为一款面向Java服务器环境的引用插件,旨在简化开发者的日常工作,提升项目的可维护...
《伦齐手表:索尼SmartWatch 2的索迪斯食品清单扩展详解》 在智能穿戴设备领域,索尼SmartWatch 2...随着技术的发展,我们有理由期待更多类似“lunzziwatch”的创新应用,让智能穿戴设备更好地服务于我们的日常生活。
通过对Yoonsik Cheon 和 Carlos Chavez的研究成果的学习,我们可以了解到将现有的Android原生应用转换为Flutter应用不仅能够帮助开发者节省开发成本,提高应用质量和性能,还能更好地适应多平台的市场需求。...