Merge pull request #123 from 1326670425/master

附录:C++和Java的优良传统 翻译完成
This commit is contained in:
Joe
2019-07-15 12:14:44 +08:00
committed by GitHub
3 changed files with 33 additions and 4 deletions

View File

@@ -58,6 +58,7 @@
- [x] [附录:数据压缩](docs/book/Appendix-Data-Compression.md)
- [ ] [附录:对象序列化](docs/book/Appendix-Object-Serialization.md)
- [ ] [附录:静态语言类型检查](docs/book/Appendix-Benefits-and-Costs-of-Static-Type-Checking.md)
- [x] [附录:C++和Java的优良传统](docs/book/Appendix-The-Positive-Legacy-of-C-plus-plus-and-Java.md)
- [ ] [附录:成为一名程序员](docs/book/Appendix-Becoming-a-Programmer.md)

View File

@@ -137,7 +137,7 @@ Braeburn@4e25154f
因此,可以将 **Apple** 的子类型添加到被指定为保存 **Apple** 对象的集合中。
程序的输出是从 **Object** 默认的 **toString()** 方法产生的,该方法打印类名,后边跟着对象的散列码的无符号十六进制表示(这个散列码是通过 **hashCode()** 方法产生的)。将在[附录理解equals和hashcode方法]()中了解有关散列码的内容。
程序的输出是从 **Object** 默认的 **toString()** 方法产生的,该方法打印类名,后边跟着对象的散列码的无符号十六进制表示(这个散列码是通过 **hashCode()** 方法产生的)。将在[附录理解equals和hashCode方法]()中了解有关散列码的内容。
<!-- Basic Concepts -->
## 基本概念
@@ -1789,13 +1789,18 @@ Serializable]
尽管存在这些问题但Java集合仍是在日常工作中使用的基本工具它可以使程序更简洁、更强大、更有效。你可能需要一段时间才能熟悉集合类库的某些方面但我想你很快就会找到自己的路子来获得和使用这个类库中的类。
[^1]: 许多语言例如PerlPython和Ruby都有
集合的本地支持。
[^1]: 许多语言例如PerlPython和Ruby都有集合的本地支持。
[^2]: 这里是操作符重载的用武之地C++和C#的集合类都使用操作符重载生成了更简洁的语法
[^3]: 在[泛型]()章节的末尾,有个关于这个问题是否很严重的讨论。但是,[泛型]()章节还将展示Java泛型远不止是类型安全的集合这么简单。
[^4]: **remove()** 是一个所谓的“可选”方法(还有一些其它的这种方法),这意味着并非所有的 **Iterator** 实现都必须实现该方法。这个问题将在[附录:集合主题]()中介绍。但是标准Java库集合实现了 **remove()** ,因此在[附录:集合主题]()章节之前,都不必担心这个问题。
[^5]: 这实际上依赖于具体实现。优先级队列算法通常会按插入顺序排序(维护一个*堆*),但它们也可以在删除时选择最重要的元素。 如果对象的优先级在它在队列中等待时可以修改,那么算法的选择就显得很重要了。
[^6]: 有些人提倡这样一种自动创建机制,即对一个类中所有可能的方法组合都自动创建一个接口,有时候对于单个的类都是如此。 我相信接口的意义不应该仅限于方法组合的机械地复制,因此我在创建接口之前,总是要先看到增加接口带来的价值。
[^7]: 这在Java SE5之前是不可用的因为该方法被认为与操作系统的耦合度过紧因此违反“一次编写处处运行”的原则。现在提供它这一事实表明Java的设计者们更加务实了。
<!-- 分页 -->

View File

@@ -3,6 +3,29 @@
<!-- Appendix: The Positive Legacy of C++ and Java -->
# 附录: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做的那样要么就让竞争者茁壮成长。
<!-- 分页 -->
<div style="page-break-after: always;"></div>