阅读更多

66顶
91踩

企业架构

翻译新闻 离开Java,寻找更佳语言的10大理由

2009-07-15 18:02 by 见习记者 ixu 评论(129) 有54796人浏览

寻找更好的Java替代语言的10大理由

作者:Mario Fusco  

译者:liuu 

 

      别误解,其实在我的职业生涯中,我已经编写了无数的Java代码;而且,我仍然认为Java一门伟大的(程序)语言。相对于C++SmalltackJava已经有了很大的改进;但现在,即使是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>,你却不能知道运行里该范型的确切类型。同理,你也不能创建范型数组。这意味着,尽管下面的代码看起来很自然,但却不编译不了:

 

    List<String>[] listsOfStrings = new List<String>[3];

 

   6、不可避免的范型警告:你有发现过自己陷入不可能去掉的关于范型的警告么?如果你像我一样大量使用范型,我打赌你碰到过。事实上,是这个问题的规模化症状,让他们认为需要引入一个特定的注解 (@SuppressWarnings("unchecked")) 来处理这种情况,我觉得,范型应该可能被设计的更好。

 

  7、不能传void给方法调用:我得承认,这种给方法传递void的需求,乍一看有些怪异。我喜欢DSL,当我实现自己的DSL库(lambdaj)的一个特定特性时,我不得不需要一个方法声明成这样的签名:void doSomething(Object parameter),这里为这个方法传进来的参数parameter,是另一个方法调用的结果,它唯一的目的,是注册调用(的对象)自身,以可以在以后执行它。让我吃惊的是,即使println方法返回void,看上去也并没有一个好理由,不允许我把代码写成这样,:

  

   doSomething(System.out.println("test"));

 

   8、没有原生的代理机制:代理是一种非常有效和应用广泛的模式,但Java提供的代理机制,只针对接口,而不是具体类。这是为什么象cblib这样提供这种机制的库,被如此多的主流框架,如SpringHibernate,采用的原因。此外,由于cglib通过运行时创建被代理类的子类来实现的,因此这些种方式有一个众所周知的限制——不能代理final类,比如String

 

  9、差劲的Switch...case语句:Java规定,switch...case只能选择intenumJava5开始)。这一点如果跟更现代的语言如Scala相比,看起来简直太弱了。

 

  10、受检查异常(Checked exception):类似原生类型,受检查异常也已经成为Java的一个罪孽之源。它迫使程序员必须做下面两件极其糟糕讨厌的事情中的一个:让你的代码里充斥大量的、糟糕难读的、容易出错的try...catch语句,而这样做的最大意义,只是将捕获的异常,包装成运行时异常,然后再重新抛出;或者是让大量的抛出声明子句污染你的API,让接口缺少灵活性和可扩展性。

 

   真正的问题是,这里我提到的这几大主要问题,唯一的解决办法,是要做一个痛苦的决择,定义一套新的语言规范,放下当前版本的向后兼容性。我猜他们永远也不会这么做,虽然我相信,如果编写一个能够自动转换旧Java源码的程序,让它们与假设的新版本兼容,并不是很困难。最后,这就是我决定开始寻找一个更好的JVM兼容语言的原因。

 

注:原文见TSS http://www.theserverside.com/news/thread.tss?thread_id=55185,感觉作者说的还是有些道理的。 

                             

 

来自: liuu.javaeye
66
91
评论 共 129 条 请登录后发表评论
129 楼 icewind2009 2013-01-16 23:02
[img][/img]
128 楼 wnczwl369 2012-12-06 22:39
大致浏览了一下,看不懂。
127 楼 dt_flys 2012-11-06 12:20
vanezkw 写道
    Integer a = new Integer(1024);
    Integer b = new Integer(1024);
    boolean test = a < b || a == b || a > b;

这个肯定是false的。a、b都是对象,==是指比较对象的句柄,两个对象都各自分配了空间,句柄本来就不一样,==肯定是false,如果a.equals(b)就为true了。在默认情况下equals也是比较句柄,但是Integer重写了此方法,比较的是内存中的值。

严重说明基础问题的。


正因为是基础,所以问题大发了。作为一个语言不但不能让人很只观的明白代码意思,还容易制造误解,增加大量潜在BUG。在今天看来是很大的失败。
126 楼 vanezkw 2012-07-10 09:43
    Integer a = new Integer(1024);
    Integer b = new Integer(1024);
    boolean test = a < b || a == b || a > b;

这个肯定是false的。a、b都是对象,==是指比较对象的句柄,两个对象都各自分配了空间,句柄本来就不一样,==肯定是false,如果a.equals(b)就为true了。在默认情况下equals也是比较句柄,但是Integer重写了此方法,比较的是内存中的值。

严重说明基础问题的。
125 楼 ansjsun 2012-06-21 17:36
Turbo 写道
elemark 写道
ouspec 写道
elemark 写道
ouspec 写道
elemark 写道
明明是翻译,还要标原创,标题党加剽客

不厚道啊,鄙视!


新闻频道的原创基本上都是翻译自国外的文章,文章一开始已经写的很清楚,原作者是谁,译者是谁,不存在剽窃问题,请注意你的用词,谢谢。

不好意思,小弟初来乍到,不懂规矩,原来未经原作者同意的翻译在这边可以标成原创的啦?不好意思呵呵
“文章一开始已经写的很清楚,原作者是谁,译者是谁,不存在剽窃问题”,这样子啊,不过比这个开始的更开始,文章的标题是标注了“原创”标记的,我没有看错吧?
另外咱们这边好像还有“翻译”标记的,不是么?呵呵
另外,ouspec你好,请问你是哪位啊?没有表明你的执法权的话,我向你讲的任何话,都不能作为你执法的依据的哦呵呵
“新闻频道的原创基本上都是翻译自国外的文章”???你能代表新闻频道?还是这只是你自己的观点?


我是javaeye的管理员之一,我已经解释了,新闻频道的原创代表自主翻译国外的技术文章和新闻,我们的新闻频道只有原创和非原创的分别,只有在博客中有详细分:原创,翻译,随笔,转载等不同的logo,由于新闻频道绝大部分的自主新闻都是翻译自国外的技术新闻,所以,只要是javaeye自主翻译或者发布的新闻,我们都标记为原创,如果你觉得是原创logo造成的误会,可以提示管理团队把这个logo改掉。我只是觉得你指出作者剽窃,这个用词过分,文章一开始就指出了原作者是谁,翻译是谁,而且在文章结尾,给出了详细的来源网站和来源地址,怎么会说作者剽窃呢?


早晨起来看到这个真开心!昨天81楼还不是这个呢呵呵
“所以,只要是javaeye自主翻译或者发布的新闻,我们都标记为原创,如果你觉得是原创logo造成的误会,可以提示管理团队把这个logo改掉。”--真实情况不是这样的,大部分新闻(包括翻译新闻)并没有标记“原创”。
管理员大人你好啊,原来新闻这边没有“翻译”标签的啊?那我现在提示好了,请把原创logo换掉。然后我再提示一下,新闻板块加上“翻译”标签吧。
我明白辛辛苦苦的翻译成果被人说成是剽窃的滋味不好受,但是既然文章的所有内容都出自原作者,咱们只是翻译而已,就加上“原创”标记,让上天告诉我这里头一点儿剽窃的成分都没有么?
整篇的翻译,顶多是个影印版啦,影印版能加原创标记么?
请注意,这个问题是因为加上了“原创”这个logo或者标记我才说他是剽客的,如果他没有这个标记或者logo,我的观点的出发点就没有了,我就不会说他是剽客了。谢谢
所以请管理员不要轻轻带过“原创”这个logo或者标记也就是我的观点的出发点的问题,加大笔墨在我的观点--剽客上头了。另外,这不是误会,这构成了事实。
你是管理员哈,javaeye首页有个版权说明的,所有javaeye的文章都是javaeye的版权,不许转载等等一堆。那请管理员换位思考,如果javaeye的一篇绝妙中文文章,在国内非常火,结果被其他语种国家某个网站翻译并贴到了自己的首页上,你能说那个网站有版权么?他的翻译经过javaeye的允许了么?如果翻译并且贴过去还标上原创,javaeye作何想啊?就算在文章的最后一行标上了“此文章来自javaeye”,因为翻译转载带来的点击量带来的商业盈利也已经构成了不是,后面的不用我说了吧?

这个要顶



你比广电都较真....好好写程序....
124 楼 xiaokang1582830 2012-05-10 17:27
提问之前请多想想
123 楼 lsjinpeng 2012-05-02 11:47
可能是时间长了,楼主对java 基础都不是很熟悉了
122 楼 静候雨 2012-03-28 18:21
3、4、5、8、9
这些我非常同意,我是Java忠实程序员,但是我确实被这几点所困惑
第一点我不是非常同意,其实Java有内部类,可以变相的支持闭包,虽然不是像脚本语言那么方便,但至少还是形似了。

对于有原声形态,而不是对象,这一点我是深恶痛绝的,既然是面向对象为什么存在对象之外的东西?不知道当时设计者是怎么想的。也给我造成了一定的麻烦,比如说,我想获得到它的类型,我需要对那八个不应该出现的东西做判断,来返回类型!

关于泛型,我很不爽,即使我定义了一个List<String> l 的对象,最终获取出来的泛型是E,有木有搞错,我要E来何用?,它根本就无法做到运行时获得泛型。

关于switch case,这不得不说是一个很大的缺陷。让我很无语,这支持的也太少了吧!

对于第10点可以在架构上解决的!!这个不是问题,所以我不大同意。。呵呵!!

虽然Java存在如上缺点,但是我还是喜欢Java,因为我喜欢架构设计,一般都不需要理会某些确定。。
121 楼 lizeping1992 2012-03-21 11:22
没有什么是完美的。只能慢慢的接近~
120 楼 enternalttyy 2012-03-21 10:06
,有点感触
119 楼 fancyleeo 2012-03-15 14:50
这些JAVA的缺点,权当拿过来开眼界。
118 楼 fancyleeo 2012-03-15 14:49
    Intger a = new Integer(1024);

    Intger b = new Integer(1024);

    boolean test = a < b || a == b || a > b;

按照面向对象的理论理解,a和b是两个对象,而1024只是a和b的2个特征。很不幸的是,Integer貌似只有这一个特征,但是如果扩展到其他对象,你就知道为什么了。

比如:
你不能说因为2个人的头发都是黑色的,那这2个人就是一个人吧?

117 楼 liningjustsoso 2012-03-14 13:21
血腥小苹果 写道
itsoul1 写道
diggywang 写道
ldbjakyo 写道
我们就很难理解,变量test为什么是false:

    Intger a = new Integer(1024);

    Intger b = new Integer(1024);

    boolean test = a < b || a == b || a > b;

看不下去了,出来说一句。


诶 a和b 是两个东西,怎么可以这么比较。。。。。你是scale 的奸细吧????


你太可怜了,Integer对象怎么不能比较了?如果你把任何一个1024换成其它的值,返回的肯定是true!


这个本来就是false,首先a肯定不大于也不小于b,这个是值比较,a==b这个不是做值比较,而是对象引用比较,比较的是他们在内存是否指向的同一个对象,很明显不是,所以就是false了。

可是运行结果是false。是不是jdk不同。

晕,楼上的不是已经写的很清楚了么?">","<"是值比较,"=="是对象引用的比较
116 楼 liningjustsoso 2012-03-14 12:58
w582875929 写道
人有2条腿而猪有4条腿 能说这是人的缺点吗?
有筷子夹菜方便,有汤勺喝汤方便。每件东西解决的问题不一样没有可比性
如果java什么都有,那还要其他的语言干什么?正因为java没有你所说的那些缺点它才是java
如果你觉得java有很多缺点,你大可放弃它,去选择你所谓的完美的语言

哥们犀利啊,我也是这么认为的。世界上并没有完美的东西,有长处必有短处,就看你怎么用了。
115 楼 sd6733531 2011-02-28 10:41
写的很有道理!我赞同大多数作者的观点
java的switch..case..鸡肋一个。
拆装箱也很麻烦。
try{}catch{}频繁,让代码不好读。每当做I/O、jdbc,就是大量的try{}catch{}。catch{}里面还要try一个关闭。也许有时候这样分开处理很必要,但是大多时候我们不在catch里面写任何东西。(除了默认的e.printStackTrace())
感谢原创翻译。^_^
114 楼 血腥小苹果 2010-12-28 19:16
itsoul1 写道
diggywang 写道
ldbjakyo 写道
我们就很难理解,变量test为什么是false:

    Intger a = new Integer(1024);

    Intger b = new Integer(1024);

    boolean test = a < b || a == b || a > b;

看不下去了,出来说一句。


诶 a和b 是两个东西,怎么可以这么比较。。。。。你是scale 的奸细吧????


你太可怜了,Integer对象怎么不能比较了?如果你把任何一个1024换成其它的值,返回的肯定是true!


这个本来就是false,首先a肯定不大于也不小于b,这个是值比较,a==b这个不是做值比较,而是对象引用比较,比较的是他们在内存是否指向的同一个对象,很明显不是,所以就是false了。

可是运行结果是false。是不是jdk不同。
113 楼 liuyuantp 2010-10-20 16:12
看来必须有些Java功底才能看懂啊。
112 楼 jasstion 2010-10-13 12:42
你所谓的Java缺点其实有些是你自己太愚昧造成的!就比如你所说的Java异常,你自己完全可以通过对代码进行封装而避免大量的try以及Catch快啊,比如:利用拦截器,利用AOP等一系列技术!
111 楼 w582875929 2010-03-19 16:01
人有2条腿而猪有4条腿 能说这是人的缺点吗?
有筷子夹菜方便,有汤勺喝汤方便。每件东西解决的问题不一样没有可比性
如果java什么都有,那还要其他的语言干什么?正因为java没有你所说的那些缺点它才是java
如果你觉得java有很多缺点,你大可放弃它,去选择你所谓的完美的语言
110 楼 stefanoli_0705 2010-02-24 14:46
w2gavin 写道
ixu 写道
zhida 写道
我想这应该是用过Java5年以上,并且有想法的人写出的。 同感

兄台能看出这一点很不错,原文作者维护了一个有意思的开源项目lambdajhttp://code.google.com/p/lambdaj/,相当于想把lambda引入到Java,这本身就是一件很有想法的事。当然Java不仅仅是语言本身,更是一个超大的生态圈,事实上这篇文章并不是真正的要“离开Java"(包括不离开JVM),而更像是一个Java开发者,对其一直使用并喜欢的Java语言的一些缺点,发出的牢骚和不满。

个人比较认同这个观点,只是觉得Java存在改进的余地


有些地方感同身受啊,个人感觉比较恶心的就是异常处理,java现有的机制可能有一定的道理,但是能起到多大的作用不太好讲。而且额外增加了相当大的系统开销。另外比较讨厌的就是另代码的可读性大大降低。
原子类型一样,比较要命的就是要注意Integer的空指针问题,还有在方法调用的时候jvm透明的处理。很多程序设计上面的错误就是很多人误以为java方法对于所有参数的操作一视同仁造成的。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • script encoder对ASP脚本源代码进行加密工具

    script encoder对ASP脚本源代码进行加密

  • Script Encoder:screnc.exe加密解密

    从Microsoft那下载到这个小工具screnc.exe,这是命令行下的 Script Encoder(脚本加密)。它可以加密asp文件、html文件、js,vbs,sct,wsh文件,非常的方便。具体使用方法在命令行下输入 screnc /?即可查看,并且它自带有帮助说明书,我就不多介绍了。 下面介绍其简单的加密以及结合前面提到的一些解密方法来进行解密(以下的文件都保存在C:\下):...

  • 加密你的ASP页面——Script Encoder

    一、概述    一直以来,ASP技术受到了越来越多朋友的喜爱,使用ASP从事WEB开发的人也越来越多。ASP一个非常明显的特征是页面在服务器端经过处理之后发送到浏览器中的内容为标准的HTML格式,这样有效的保护了页面程序的原代码不被客户端轻易获取(当然MS的BUG不断那是另一回事了。^_^)。但是另一个普遍存在的问题是: 由于ASP页面是纯文本的形式存放,在服务器端可以轻易看到全部编程逻辑。这样给

  • Script Encoder

    Script Encoder 是一个简单的命令行工具,脚本设计者可使用此工具对他们的最终脚本进行编码,从而使 Web 主机和 Web 客户端无法查看或更改其源代码。注意,这种编码只能防止对您代码的一般性浏览,而无法防止专业黑客查看您的代码和实现方式。

  • 加密你的ASP页面——Script Encoder初探(转)

    一、概述   一直以来,ASP技术受到了越来越多朋友的喜爱,使用ASP从事WEB开发的人也越来越多。ASP一个非常明显的特征是页面在服务器端经过处理之后发送到浏览器中的内容为标准的HTML格式,这样有效的保护了页面程序的原代码不...

  • 微软ASP加密软件 sce10chs

    微软ASP加密软件Script_Encoder 用法如下: SCRDECO.EXE 加密文件 输出文件 下载地址:[url]http://download.microsoft.com/download/winscript56/Install/1.0/WIN98MeXP/CN/sce10chs.exe[/url] 一、概述 一直以来,ASP技术受到了越...

  • 加密你的ASP页面—Script Encoder初探

    一、概述 一直以来,ASP技术受到了越来越多朋友的喜爱,使用ASP从事WEB开发的人也越来越多。ASP一个非常明显的特征是页面在服务器端经过处理之后发送到浏览器中的内容为标准的HTML格式,这样有效的保护了页面程序的原代码不被客户端轻易获取(当然MS的BUG不断那是另一回事了。^_^)。但是另一个普遍存在的问题是:由于ASP页面是纯文本的形式存放,在服务器端可以轻易看到全部编程逻辑。这样给ASP

  • Microsoft Script Encoder解密代码,oask加密文件解密

    Microsoft Script Encoder解密代码,oask加密文件解密 oask中有几个文件被加了密,找了几天终于找了完整的解密程序,在这里共享给大家 可完全解密文件oask_Main.asp,oask_qfunc.asp,oask_function.asp C#版的Microsoft Script Encoder解密代码 ...

  • 用Script Encoder加密你的ASP页面

    用Script Encoder加密你的ASP页面    一直以来,ASP技术受到了越来越多朋友的喜爱,使用ASP从事WEB开发的人也越来越多。ASP一个非常明显的特征是页面在服务器端经过处理之后发送到浏览器中的内容为标准的HTML格式,这样有效的保护了页面程序的原代码不被客户端轻易获取。但是另一个普遍存在的问题是:由于ASP页面是纯文本的形式存放,在服务器端可以轻易看到全部编程逻辑。这样给AS...

  • Active Server Pages 错误 'ASP 0240'

    在WEB服务器上打开任何ASP网页出现如下错误: Active Server Pages 错误 ASP 0240 Script Engine 异常 /index.asp 一个 ScriptEngine 超出了预期C0000005 在IActiveScriptParse::ParseScriptText(),来自CActiveScriptEngine::AddScriptlet()

  • 用MS script encode加密asp

    Active Server Page技术为应用开发商提供了基于脚本的直观、快速、高效的应用开发手段,极大地提高了开发的效果。但由于ASP脚本是采用明文(plain text)方式来编写的,所以应用开发商辛苦开发出来的ASP应用程序,一旦发布到运行环境中去后,就很难确保这些“源代码”不会被流传出去。这样就产生了如何有效地保护开发出来的ASP脚本源代码的需求。ASP运行机制ASP脚本是一系列按特定语法

Global site tag (gtag.js) - Google Analytics