王垠:给 Java 说句公道话
有些人问我,在现有的语言里面,有什么好的推荐?我说:“Java。” 他们很惊讶:“什么?Java!” 所以我现在来解释一下。
(题图来自:staticworld.net)
Java 超越了所有咒骂它的“动态语言”
也许是因为年轻人的逆反心理,人们都不把自己的入门语言当回事。很早的时候,计算机系的学生用 Scheme 或者 Pascal 入门,现在大部分学校用 Java。这也许就是为什么很多人恨 Java,瞧不起用 Java 的人。提到 Java,感觉就像是爷爷那辈人用的东西。大家都会用 Java,怎么能显得我优秀出众呢?于是他们说:“Java 老气,庞大,复杂,臃肿。我更愿意探索新的语言……”
某些 Python 程序员,在论坛里跟初学者讲解 Python 有什么好,其中一个原因竟然是:“因为 Python 不是 Java!” 他们喜欢这样宣传:“看 Python 多简单清晰啊,都不需要写类型……” 对于 Java 的无缘无故的恨,盲目的否认,导致了他们看不到它很重要的优点,以至于迷失自己的方向。虽然气势上占上风,然而其实 Python 作为一个编程语言,是完全无法和 Java 抗衡的。
在性能上,Python 比Java 慢几十倍。由于缺乏静态类型等重要设施,Python 代码有 bug 很不容易发现,发现了也不容易 debug,所以 Python 无法用于构造大规模的,复杂的系统。你也许发现某些 startup 公司的主要代码是 Python 写的,然而这些公司的软件,质量其实相当的低。在成熟的公司里,Python 最多只用来写工具性质的东西,或者小型的,不会影响系统可靠性的脚本。
静态类型的缺乏,也导致了 Python 不可能有很好的 IDE 支持,你不能完全可靠地“跳转到定义”,不可能完全可靠地重构 Python 代码。PyCharm 对于早期的 Python 编程环境,是一个很大的改进,然而理论决定了,它不可能完全可靠地进行“变量换名”等基本的重构操作。就算是比 PyCharm 强大很多的 PySonar,对此也无能为力。由于 Python 的设计过度的“动态”,没有类型标记,使得完全准确的定义查找,成为了不可判定的问题。
在设计上,Python,Ruby 比起 Java,其实复杂很多。缺少了很多重要的特性,有毛病的“强大特性”倒是多了一堆。由于盲目的推崇所谓“正宗的面向对象”方式,所谓“ late binding ”,这些语言里面有太多可以“重载”语义的地方,不管什么都可以被重定义,这导致代码具有很大的不确定性和复杂性,很多 bug 就是被隐藏在这些被重载的语言结构里面了。因此,Python 和 Ruby 代码很容易被滥用,不容易理解,容易写得很乱,容易出问题。
很多 JavaScript 程序员也盲目地鄙视 Java,而其实 JavaScript 比 Python 和 Ruby 还要差。不但具有它们的几乎所有缺点,而且缺乏一些必要的设施。JavaScript 的各种“WEB 框架”,层出不穷,似乎一直在推陈出新,而其实呢,全都是在黑暗里瞎蒙乱撞。JavaScript 的社区以幼稚和愚昧著称。你经常发现一些非常基本的常识,被 JavaScript “专家”们当成了不起的发现似的,在大会上宣讲。我看不出来 JavaScript 社区开那些会议,到底有什么意义,仿佛只是为了拉关系找工作。
Python 凑合可以用在不重要的地方,Ruby 是垃圾,JavaScript 是垃圾中的垃圾。原因很简单,因为 Ruby 和 JavaScript 的设计者,其实都是一知半解的民科。然而世界就是这么奇怪,一个彻底的垃圾语言,仍然可以宣称是“程序员最好的朋友”,从而得到某些人的爱戴……
Java 的“继承人”没能超越它
最近一段时间,很多人热衷于 Scala,Clojure,Go 等新兴的语言,他们以为这些是比 Java 更现代,更先进的语言,以为它们最终会取代 Java。然而这些狂热分子们逐渐发现,Scala,Clojure 和 Go 其实并没有解决它们声称能解决的问题,反而带来了它们自己的毛病,而这些毛病很多是 Java 没有的。然后他们才意识到,Java 离寿终正寝的时候,还远得很……
Go语言
关于 Go,我已经评论过很多了,有兴趣的人可以看这里。总之,Go 是民科加自大狂的产物,奇葩得不得了。这里我就不多说它了,只谈谈 Scala 和 Clojure。
Scala
我认识一些人,开头很推崇 Scala,仿佛什么救星似的。我建议他们别去折腾了,老老实实用 Java。没听我的,结果到后来,成天都在骂 Scala 的各种毛病。但是没办法啊,项目上了贼船,不得不继续用下去。我不喜欢进行人身攻击,然而我发现一个语言的好坏,往往取决于它的设计者的背景,觉悟,人品和动机。很多时候我看人的直觉是异常的准,以至于依据对语言设计者的第一印象,我就能预测到这个语言将来会怎么发展。在这里,我想谈一下对 Scala 和 Clojure 的设计者的看法。
Scala 的设计者 Martin Odersky,在 PL 领域有所建树,发表了不少学术论文( 包括著名的《The Call-by-Need Lambda Calculus》),而且还是大名鼎鼎的 Niklaus Wirth 的门徒,我因此以为他还比较靠谱。可是开始接触 Scala 没多久,我就很惊讶的发现,有些非常基本的东西,Scala 都设计错了。这就是为什么我几度试图采用 Scala,最后都不了了之。因为我一边看,一边发现让人跌眼镜的设计失误,而这些问题都是 Java 没有的。这样几次之后,我就对 Odersky 失去了信心,对 Scala 失去了兴趣。
回头看看 Odersky 那些论文的本质,我发现虽然理论性貌似很强,其实很多是在故弄玄虚(包括那所谓的“call-by-need lambda calculus”)。他虽然对某些特定的问题有一定深度,然而知识面其实不是很广,眼光比较片面。对于语言的整体设计,把握不够好。感觉他是把各种语言里的特性,强行拼凑在一起,并没有考虑过它们是否能够“和谐”的共存,也很少考虑“可用性”。
由于 Odersky 是大学教授,名声在外,很多人想找他拿个 PhD,所以东拉西扯,喜欢往 Scala 里面加入一些不明不白,有潜在问题的“特性”,其目的就是发 paper,混毕业。这导致 Scala 不加选择的加入过多的特性,过度繁复。加入的特性很多后来被证明没有多大用处,反而带来了问题。学生把代码实现加入到 Scala 的编译器,毕业就走人不管了,所以 Scala 编译器里,就留下一堆堆的历史遗留垃圾和 bug。这也许不是 Odersky 一个人的错,然而至少说明他把关不严,或者品位确实有问题。
最有名的采用 Scala 的公司,无非是 Twitter。其实像 Twitter 那样的系统,用 Java 照样写得出来。Twitter 后来怎么样了呢?CEO 都跑了 :P 新 CEO 上台就裁员300多人,包括工程师在内。我估计 Twitter 裁员的一个原因是,有太多的 Scala 程序员,扯着各种高大上不实用的口号,比如“函数式编程”,进行过度工程,浪费公司的资源。花着公司的钱,开着各种会议,组织各种 meetup 和 hackathon,提高自己在 open source 领域的威望,其实没有为公司创造很多价值……
Clojure
再来说一下 Clojure。当 Clojure 最初“横空面世”的时候,有些人热血沸腾地向我推荐。于是我看了一下它的设计者 Rich Hickey 做的宣传讲座视频。当时我就对他一知半解拍胸脯的本事,印象非常的深刻。Rich Hickey 真的是半路出家,连个 CS 学位都没有。可他那种气势,仿佛其他的语言设计者什么都不懂,只有他看到了真理似的。不过也只有这样的人,才能创造出“宗教”吧?
满口热门的名词,什么 lazy 啊,pure 啊,STM 啊,号称能解决“大规模并发”的问题,…… 这就很容易让人上钩。其实他这些词儿,都是从别的语言道听途说来,却又没能深刻理解其精髓。有些“函数式语言”的特性,本来就是有问题的,却为了主义正确,为了显得高大上,抄过来。所以最后你发现这语言是挂着羊头卖狗肉,狗皮膏药一样说得头头是道,用起来怎么就那么蹩脚。
Clojure 的社区,一直忙着从 Scheme 和 Racket 的项目里抄袭思想,却又想标榜是自己的发明。比如 Typed Clojure,就是原封不动抄袭 Typed Racket。有些一模一样的基本概念,在 Scheme 里面都几十年了,恁是要改个不一样的名字,免得你们发现那是 Scheme 先有的。甚至有人把 SICP,The Little Schemer 等名著里的代码,全都用 Clojure改写一遍,结果完全失去了原作的简单和清晰。最后你发现,Clojure 里面好的地方,全都是 Scheme 已经有的,Clojure 里面新的特性,几乎全都有问题。我参加过一些 Clojure 的 meetup,可是后来发现,里面竟是各种喊着大口号的小白,各种趾高气昂的民科,愚昧之至。
如果现在要做一个系统,真的宁可用 Java,也不要浪费时间去折腾什么 Scala 或者 Clojure。错误的人设计了错误的语言,拿出来浪费大家的时间。
Java 没有特别讨厌的地方
我至今不明白,很多人对 Java 的仇恨和鄙视,从何而来。它也许缺少一些方便的特性,然而长久以来用 Java 进行教学,用 Java 工作,用 Java 开发 PySonar,RubySonar,Yin 语言,…… 我发现 Java 其实并不像很多人传说的那么可恶。我发现自己想要的95%以上的功能,在 Java 里面都能找到比较直接的用法。剩下的5%,用稍微笨一点的办法,一样可以解决问题。
盲目推崇 Scala 和 Clojure 的人们,很多最后都发现,这些语言里面的“新特性”,几乎都有毛病,里面最重要最有用的特性,其实早就已经在 Java 里了。有些人跟我说:“你看,Java 做不了这件事情!” 后来经我分析,发现他们在潜意识里早已死板的认定,非得用某种最新最酷的语言特性,才能达到目的。Java 没有这些特性,他们就以为非得用另外的语言。其实,如果你换一个角度来看问题,不要钻牛角尖,专注于解决问题,而不是去追求最新最酷的“写法”,你就能用 Java 解决它,而且解决得干净利落。
很多人说 Java 复杂臃肿,其实是因为早期的 Design Patterns,试图提出千篇一律的模板,给程序带来了不必要的复杂性。然而 Java 语言本身跟 Design Patterns 并不是等价的。Java 的设计者,跟 Design Pattern 的设计者,完全是不同的人。你完全可以使用 Java 写出非常简单的代码,而不使用 Design Patterns。
Java 只是一个语言。语言只提供给你基本的机制,至于代码写的复杂还是简单,取决于人。把对一些滥用 Design Patterns 的Java 程序员的恨,转移到 Java 语言本身,从而完全抛弃它的一切,是不明智的。
结论
我平时用着 Java 偷着乐,本来懒得评论其它语言的。可是实在不忍心看着有些人被 Scala 和 Clojure 忽悠,所以在这里说几句。如果没有超级高的性能和资源需求(可能要用 C 这样的低级语言),目前我建议就老老实实用 Java 吧。虽然不如一些新的语言炫酷,然而实际的系统,还真没有什么是 Java 写不出来的。少数地方可能需要绕过一些限制,或者放宽一些要求,然而这样的情况不是很多。
编程使用什么工具是重要的,然而工具终究不如自己的技术重要。很多人花了太多时间,折腾各种新的语言,希望它们会奇迹一般的改善代码质量,结果最后什么都没做出来。选择语言最重要的条件,应该是“够好用”就可以,因为项目的成功最终是靠人,而不是靠语言。既然 Java 没有特别大的问题,不会让你没法做好项目,为什么要去试一些不靠谱的新语言呢?
- brucezhou [WeChat 6.3|Android 4.4] 2016-02-20 16:00 8 赞 回复
- 还是用我的OCaml
- [1]来自浙江温州的 Firefox 43.0|Ubuntu 用户 发表于 2016-02-01 16:37 的评论:观点偏激了点,从商业角度说js是趋势,相对简单,能挣钱。
- 来自浙江的 Chrome 47.0|GNU/Linux 用户 2016-02-04 19:43 7 赞 回复
- 观点偏激了点,从商业角度说Office办公软件是趋势,相对简单,能挣钱。
- 来自北京的 Safari 9.0|Mac 10.11 用户 2016-02-04 11:09 8 赞 回复
- 观点太过偏激,每个语言都有优点,而作者把其他语言的优点都忽略了,用java的优点来对比其他语言的缺点,就好像是用僵尸和植物来做比较,这么比较有意义吗?对了,植物可以打僵尸
- [1]来自美国的 Chrome 46.0|Windows 7 用户 发表于 2016-01-30 02:30 的评论:很多时候只是应用领域不同而已 你见过有人用java做游戏? 慢的一比 现在市场上web用java最多的地方就是金融产业 但是java开发效率比php和node 甚至python ruby都慢, 框架冗长 麻烦 我觉得以后肯定是趋于快速开发 保证性能的情况下 越快越好 所以javascript肯定会雄起的[2]来自湖北武汉的 Chrome 48.0|Fedora 用户 发表于 2016-01-30 21:28 的评论:Minecraft这个游戏史上的奇迹就这样被你扔了。底层都是OpenGL就随便下个慢的定义是不是太武断了。[3]Pucmax [Chrome 47.0|Windows 7] 发表于 2016-02-01 12:29 的评论:某个语言写的游戏慢,肯定是某个特定的环节导致了慢,这和语言本身的关系或许并没有想象中那么大。
- 枫落夜舞 [Chrome 48.0|Windows 10] 2016-02-04 10:06 4 赞 回复
-
并不是这样,不同语言的底层实现机制不同,性能差距十分明显,诸如Python、Ruby这样的脚本语言,性能比起C、C++、Rust、Golang这类直接编译成NativeCode的语言要差了一个数量级以上(10倍+),因此这类脚本语言就不可能用作大型游戏引擎开发、图形处理等性能要求高的领域。
当然,游戏开发也有部分会用到脚本语言(比如Lua),但都是用在性能不敏感的逻辑部分。
- 来自湖北武汉的 Chrome 47.0|Fedora 用户 2016-02-03 14:16 5 赞 回复
- 评论前先搞清楚文章是从哪个角度评价的,不要扯到商业层面,商业层面从来都是不理智的。其他道理我不懂,我不搞语言设计,就个人接触十几种语言来看,单从使用感受上来讲,c和java是最舒服的,其次是js,但是js有其固有的一些缺点应用面暂时不是特别广。至于其他语言都不行,尤其是新出现的一些语言,充斥着过度设计和语义混乱。
- 7th [Firefox 44.0|GNU/Linux] 2016-02-03 10:18 7 赞 回复
- 能顺利完成工作就好了,管你用什么语言!
- 来自美国的 Chrome 48.0|GNU/Linux 用户 2016-02-03 09:29 11 赞 回复
- 顶级CS牛校的必修课普遍都用Java和C教的. 后面的话感觉没必要说了, 因为大部分喜欢黑Java的人连CS是啥都不知道..
- 来自广西梧州的 Safari 8.0|Mac 10.10 用户 2016-02-01 21:46 8 赞 回复
- 赞同回复在此之前的评论,确实挣钱的语言,让很多从实现上而言更好的语言处境更好(受到程序员爱戴什么的)。Scala、Clojure、Groovy之类的语言的出现,它们弥补了Java在以实现功能为目的实用力不足,要知道市场上堆代码的本质目标是完成功能,而不是把业务逻辑抽象这件事。
- [1]来自浙江温州的 Firefox 43.0|Ubuntu 用户 发表于 2016-02-01 16:37 的评论:观点偏激了点,从商业角度说js是趋势,相对简单,能挣钱。
- 来自浙江温州的 Firefox 43.0|Ubuntu 用户 2016-02-01 16:42 6 赞 回复
- 我认为语言之间没什么差异,哪个能挣钱,给公司带来更多的经济效益就学哪个,当然,可以从偏好来进行选择,喜好或者市场需求,不过js就是js,不要从js框架开始进行就好了
- Pucmax [Chrome 47.0|Windows 7] 2016-02-01 12:27 8 赞 回复
-
Java确实正在被抛弃,尽管它已经被补充的很完善,人们一直在寻找一种更好的语言。Python确实只是在用于搜索引擎和游戏引擎,Java和它比当然优势巨大,但也是五五开而已。
如楼上所说,有人说PHP天下无敌,只能说在现有需求范畴之下,PHP封装的很到位,看似强大。
像PHP这样,语言靠社会经济推动、被动发展的,就能让我们Java码农从Java本身跳出来、看到很多问题。
然而提到NodeJs和Go等,个人觉得作者确实还没有深入。很多时候,我们拿着手头用了上十年的Java,却在感叹着其他语言是如何的犀利。习惯了Java的套路之后,总觉得转型困难,甚至不愿意转型。其实这是错误的,Java适合写书和编程入门,但绝不适合支持思想的保守。
诚然,一些成熟的用Java来实现的系统,我们没必要换个语言重写一遍,那纯粹是浪费钱。但新系统方面,建议不要主动拒绝新的思维。
- z75315 [Chrome 48.0|Windows 7] 2016-02-01 11:43 3 赞 回复
- 不懂语言,不过尺有所短,寸有所长。这是见仁见智的事情,应该不值得打架拍砖。
- [1]来自江苏无锡的 Firefox 38.0|GNU/Linux 用户 发表于 2016-01-29 08:59 的评论:是本人吗?跌份
- 来自湖北武汉的 Chrome 48.0|Fedora 用户 2016-01-29 23:19 4 赞 回复
- 王大师一直用Java,觉得不是本人只能说你不熟悉他。
- fanbt [Firefox 43.0|Fedora] 2016-01-29 13:29 10 赞 回复
-
对于厂商来说,JAVA很好,因为它可以缩短项目的研发周期,还有就是程序员好找。
对于用户来说,JAVA真的一点都不好,执行效率低得不是一星半点,给个真实的案例吧,我们去年上的两个系统,一个NC,一个OA,都是基于JAVA开发的,用起来感觉我又回到了10年前……,最最郁闷的是,两个系统对JAVA的版本要求还不一样,妈的,还让不让人活了?