`
opensdp
  • 浏览: 77304 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

10个让我去寻找比Java更好的语言的理由

阅读更多

 

别误会我. 在我的职业生涯中我写了无数的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评论  

26
9
分享到:
评论
10 楼 mylazygirl 2009-12-17  
9.case还可以传byte,char看过think in java 的都知道吧
9 楼 alanwu 2009-10-13  
LZ很早就关注Scala了
8 楼 sangdiyage 2009-09-01  
LZ,我支持上楼的说法,对象怎么能用==号呢,==是检测对象的地址是否放在同一位置的,你的a和b是两个不同的对象,所以存在的地址应该是不同的,那就不能用==了!,所以返回的肯定是false哈!
7 楼 heipn 2009-09-01  
最讨厌这种讨论语言的贴
6 楼 liu78778 2009-08-31  
LZ真牛啊..不是自己写的也敢用个 原 字
5 楼 dugu666 2009-08-31  
我倒是觉得异常检测太有价值了!!!自从用了它,我不再担心我的网页由于网络连接或者数据等原因造成页面出现错误了!!!居然说“异常检测”是java原罪之一,实在不敢苟同!
4 楼 422759366 2009-08-31  
做什么东西的需要把java语言改变。人工智能?
3 楼 zht110227 2009-08-31  
第三点,真正的对象传的是引用?这个不是吧,应该还是传的是值吧,只不过这个值比较特殊,是个对象的地址值而已。
2 楼 天机老人 2009-08-26  
scala相对ruby开发差多少?
1 楼 狂放不羁 2009-08-26  
呵呵,对于第4点,不同对象用==比较当然会不相同,==比较引用。
ps:目前我也对scala感兴趣。

相关推荐

Global site tag (gtag.js) - Google Analytics