Files
OnJava8/docs/book/Appendix-The-Positive-Legacy-of-C-plus-plus-and-Java.md
2019-07-15 11:41:56 +08:00

5.1 KiB
Raw Blame History

[TOC]

附录:C++和Java的优良传统

在各种讨论声中有一些人认为C++是一种设计糟糕的语言。 我认为理解C++和Java语言的选择有助于了解更大的视角。

也就是说我几乎不再使用C++了。当我使用它的时候要么是用来检查遗留代码要么是编写性能关键performance-critical部分程序通常尽可能小以便用其他语言编写的其他程序来调用。

因为我在最初的8年里一直在C++标准委员会工作所以我见证了那些被做出的决定。它们都经过了极其谨慎的考虑远远超过了许多在Java中做出的决定。

然而正如人们正确地指出的那样由此产生的语言使用起来既复杂又痛苦而且只要我一段时间不使用它我就会忘记那些古怪的规则。在我写书的时候我是从第一原理first principles处了解这些规则的而不是记住了它们。

为了理解C++语言为何既令人不愉快且复杂同时又是精心设计的必须要牢记C++中所有内容的主要设计决策与C. Bjarne Stroustrup该语言的创造者即“C++之父”的兼容性决定。这样的设计似乎是为了可以让大量的C程序员透明地转移到对象代指C++允许他们在C++下编译他们的C代码。这是一个巨大的限制一直是C++最大的优势......而且也是它的祸根。这就是使得C++成功的原因,也是使它复杂的原因。

它也欺骗了那些不太了解C++的Java设计师。例如他们认为运算符重载对于程序员来说很难正确使用。这在C++中基本上是正确的因为C++既有栈分配又有堆分配你必须重载运算符来处理所有情况而且不要造成内存泄漏。这确实很困难。然而Java有单一的内存分配机制和一个垃圾收集器这使得运算符重载变得微不足道正如C中那样但在早于Java的Python中已经可以看到。但多年来来自Java团队的一贯态度是“运算符重载太复杂了”。这里还有许多决策所做的事明显不应该是他们做的。正是由于这些原因让我有了蔑视Gosling即“Java之父”和Java团队决策的名声。Java 7和8由于某种原因包含了更好的决策。但是向后兼容性这个约束总是会阻碍真正的改进。语言永远不会是它本来的样子。

还有很多其他的例子。“为了提高效率必须包含基本类型”坚持“万物皆对象”是正确的当对性能有要求的时候提供一个陷阱门trap door来做低级别的活动lower-level activities这里也可以使用hotspot技术透明地提高性能正如他们最终做的那样不能直接使用浮点处理器去计算超越函数它用软件来完成。我已经尽可能多地提出了这样的问题但我得到的却一直是类似“这是Java方式”这样的回复。

当我提出关于泛型的设计有多糟糕的时候我得到了相同的回复以及“我们必须向后兼容那样以前用Java做出的决策”即使它们是糟糕的决策。最近越来越多的人已经获得了足够的泛型经验可以发现泛型真的很难用。事实上C++模板更强大、更一致现在更容易使用因为编译器的错误消息是可以容忍的。人们一直在认真对待物化reification这可能是有用的东西但是在那种被严格约束所削弱的设计中并没有多大影响。

这样的例子还有很多很多。这是否意味着Java失败了绝对不。Java将程序员的主流带入了垃圾收集、虚拟机和一致的错误处理模型的世界。由于它的所有缺陷它将我们提升到了一个水平现在我们已经准备好使用更高级别的语言了。

有一点C++是领先的语言人们认为它总是如此。许多人对Java有同样的看法但由于JVMJava使得取代自己变得更加容易。现在有可能会有人创建一种新语言并使其在短时间内像Java一样高效运行。以前为新语言开发一个正确有效的编译器需要花费大部分开发时间。

这种情况已经发生了包括像Scala这样的高级静态语言以及动态语言新的且可移植的如GroovyClojureJRuby和Jython。这是未来并且过渡很顺畅因为可以很轻易地将这些新语言与现有Java代码结合使用并且必要时可以重写那些在Java中的瓶颈。

在撰写本文时Java是世界上的头号编程语言。然而Java最终将会减弱就像C++一样沦只在特殊情况下使用或者只是用来支持传统的代码因为它不能像C++那样和硬件连接。但是无意中的好处也是Java真正意外的光彩之处在于它为自己的替代品创造了一条非常畅通的道路即使Java本身已经达到了无法再发展的程度。未来所有的语言都应该从中学习要么创建一个可以重构的文化像Python和Ruby做的那样要么就让竞争者茁壮成长。