翻译数据存储

This commit is contained in:
LingCoder
2019-01-09 02:04:17 +08:00
parent 54968fa660
commit 98b7d9c576

View File

@@ -2,18 +2,18 @@
>如果我们说不同的语言,我们会感觉到一个不同的世界!— Ludwig Wittgenstein (1889-1951)
尽管 Java 基于 C++ ,但 Java 是一种更纯粹的面向对象程序设计语言。Java 和 C++ 都是混合语言。在 Java 中,语言设计者认为混合并不像 C++ 那样重要。混合语言允许多种编程风格;这也是 C++ 支持与 C 语言的向后兼容性原因。因为 C++ 是 C 语言的超集,所以它也包含了许多 C 语言的不良特性,这可能使得 C++ 在某些方面过于复杂。
尽管 Java 基于 C++ ,但 Java 是一种更纯粹的面向对象程序设计语言。Java 和 C++ 都是混合语言。在 Java 中,语言设计者认为混合并不像 C++ 那样重要。混合语言允许多种编程风格;这也是 C++ 支持与 C 语言的向后兼容性原因。因为 C++ 是 C 语言的超集,所以它也包含了许多 C 语言的不良特性,这可能使得 C++ 在某些方面过于复杂。
Java 语言预设你已经编写过面对对象的程序。在此之前,你必须将自己的思维置于面对对象的世界。在本章中你将了解 Java 语言的基本组成,学习 Java (几乎)万物皆对象的思想。
<!-- You Manipulate Objects with References -->
## 对象操纵
称意味着什么?例如:所有叫“玫瑰”的花闻起来很甜蜜。(引用自 莎士比亚,《罗密欧与朱丽叶》)。
字的意义在于,我们听到“玫瑰”,就会想到一种闻起来很甜蜜的的花。(引用自 莎士比亚,《罗密欧与朱丽叶》)。
所有的编程语言都会操纵内存中的元素。有时程序员必须要有意识地直接或间接地操纵它们。示例:在 C/C++ 语言中是通过指针来完成操作的。
Java 使用万物皆对象的思想和特有的语法方式来简化问题。虽然万物皆可为对象,但你操纵的标识符实际上是只对象的“引用”示例:我们可以将这种“引用”想象成电视(对象)和遥控器(引用)之间的关系。只要拥有对象的“引用”,就可以操纵该“对象”。我们无需直接接触电视,只要掌握遥控器就可以在房中自由地控制电视(对象)的频道和音量。此外,没有电视机,遥控器也可以单独存在。引申来说,仅仅因为你有一个“引用”并不意味着你必然有一个关联的“对象”。
Java 使用万物皆对象的思想和特有的语法方式来简化问题。虽然万物皆可为对象,但你操纵的标识符实际上是只对象的“引用” [^1]。 示例:我们可以将这种“引用”想象成电视(对象)和遥控器(引用)之间的关系。只要拥有对象的“引用”,就可以操纵该“对象”。我们无需直接接触电视,只要掌握遥控器就可以在房中自由地控制电视(对象)的频道和音量。此外,没有电视机,遥控器也可以单独存在。引申来说,仅仅因为你有一个“引用”并不意味着你必然有一个关联的“对象”。
下面来创建一个 String 的引用,用于保存单词语句。代码示例:
@@ -40,74 +40,24 @@ Java 语法允许我们使用带双引号的文本内容来初始化字符串。
以上的代码示例展示了字符串对象的创建过程以及如何初始化生成字符串。Java 本身自带了许多现成的数据类型,在此基础之上我们还可以创建自己的数据类型。类型的创建是 Java 的基本操作。在本书后面的学习中将会接触到。
<!-- Where Storage Lives -->
### 对象存储
### 数据存储
那么, 程序在运行时是如何安排内存的呢?下面我们就来形象地描述下, Java 程序在内存中存储的5个不同的地方
那么, 程序在运行时是如何存储的呢?尤其是内存。下面我们就来形象地描述下, Java 中数据存储的5个不同的地方
1. Registers. This is the fastest storage because it exists in a place different
from that of other storage: inside the central processing
unit (CPU)2. However, the number of registers is severely limited, so
registers are allocated as they are needed. You dont have direct
control over register allocation, nor do you see any evidence in
your programs that registers even exist (C & C++, on the other
hand, allow you to suggest register allocation to the compiler).
2. The stack. This lives in the general random-access memory
(RAM) area, but has direct support from the processor via its
stack pointer. The stack pointer is moved down to create new
memory and moved up to release that memory. This is an
extremely fast and efficient way to allocate storage, second only to
registers. The Java system must know, while it is creating the
program, the exact lifetime of all the items stored on the stack.
This constraint places limits on the flexibility of your programs, so
while some Java storage exists on the stack—in particular, object
references—Java objects themselves are not placed on the stack.
3. The heap. This is a general-purpose pool of memory (also in the
RAM area) where all Java objects live. Unlike the stack, the
compiler doesnt need to know how long objects must stay on the
heap. Thus, theres a great deal of flexibility when using heap
storage. Whenever you need an object, you write the code to
create it using new, and the storage is allocated on the heap when
that code is executed. Theres a price for this flexibility: It can take
more time to allocate and clean up heap storage than stack
storage (if you even could create objects on the stack in Java, as
you can in C++). Over time, however, Javas heap allocation
mechanism has become very fast, so this is not an issue for
concern.
4. Constant storage. Constant values are often placed directly in
the program code, which is safe since they can never change.
Sometimes constants are cordoned off by themselves so they can
be optionally placed in read-only memory (ROM), in embedded
systems. 3
5. Non-RAM storage. If data lives completely outside a program,
it can exist while the program is not running, outside the control
of the program. The two primary examples of this are serialized
objects, where objects are turned into streams of bytes, generally
sent to another machine, and persistent objects, where the objects
are placed on disk so they will hold their state even when the
program is terminated. The trick with these types of storage is
turning the objects into something that exist on the other
medium, and yet be resurrected into a regular RAM-based object
when necessary. Java provides support for lightweight
persistence. Libraries such as JDBC and Hibernate provide more
sophisticated support for storing and retrieving object
information using databases.
1. **寄存器** *Registers* 最快的保存区域位于CPU内部 [^2]。然而寄存器的数量十分有限所以寄存器是根据需要由编译器分配。我们对其没有直接的控制权也无法在自己的程序里找到寄存器存在的踪迹另一方面C/C++ 允许开发者向编译器建议寄存器的分配)。
程序运行时,我们最好要对数据保存到何处做到心中有数。特别要注意的是。有六个地方都可
以保存数据:
2. **栈内存***Stack* 存在于通用随机存取存储器RAM区域中可通过栈指针获得处理器的直接支持。栈指针向下移动以创建新内存并向上移动以释放该内存后进先出速度仅次于寄存器。创建程序时Java 编译器必须准确地知道栈内保存的所有数据的“长度”以及生命周期。这种约束限制了程序的灵活性。因此,虽然栈内存上存在一些 Java 数据,特别是对象引用,但 Java 对象本身却是保存在堆内存的。
(1) 寄存器。这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹
3. **堆内存***Heap* 这是一个常规用途的内存池(也在 RAM区域所有 Java 对象都存在于其中。与堆栈不同,编译器不需要知道对象必须在堆上停留多长时间。因此,用堆内存保存数据更具灵活性。创建一个对象时,只需用 new 命令实例化代码即可。执行这些代时,会在堆里自动进行数据的保存。这种灵活性是有代价的:分配和清理堆内存要比栈内存需要更多的时间(如果你甚至可以用 Java 在栈内存上创建对象就像在C++ 中那样。随着时间的推移Java 的堆内存分配机制现已非常快了,因此这不是一个值得关心的问题了
(2) 堆栈。驻留于常规 RAM随机访问存储器区域但可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移会创建新的内存若向上移则会释放那些内存。这是一种特别快、特别有效的数据保存方式仅次于寄存器。创建程序时Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码以便向上和向下移动指针。这一限制无疑影响了程序的灵活性所以尽管有些Java 数据要保存在堆栈里——特别是对象句柄但Java 对象并不放到其中
(3) 堆。一种常规用途的内存池(也在 RAM区域其中保存了Java 对象。和堆栈不同“内存堆”或“堆”Heap最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间也不必知道存储的数据要在堆里停留多长的时间。此用堆保存数据时会得到更大的灵活性。要求创建一个对象时只需用new命令编制相关的代码即可。执行这些代时会在堆里自动进行数据的保存。当然为达到这种灵活性必然会付出一定的代价在堆里分配存储空间时会花掉更长的时间
4. **常量存储** *Constant storage* 常量值通常直接放在程序代码中因为它们永远不会改变。如需严格保护可考虑将它们置于只读存储器ROM中 [^3]
(4) 静态存储。这儿的“静态”Static是指“位于固定位置”尽管也在 RAM里程序运行期间静态存储的数据将随时等候调用。可用static 关键字指出一个对象的特定元素是静态的。但 Java 对象本身永远都不会置入静态存储空间
5. **非 RAM 存储** *Non-RAM storage* 数据完全存在于程序之外,在程序运行以及脱离程序控制后依然存在。两个主要的例子1序列化对象对象被转换为字节流通常被发送到另一台机器2持久化对象对象被放置在磁盘上即使程序终止数据依然存在。这些存储的方式都是将对象转存于另一个介质中并在需要时恢复到常规内存中。Java 为轻量级持久性提供支持。诸如 JDBC 和 Hibernate 之类的库为使用数据库存储和检索对象信息提供了更复杂的支持
(5) 常数存储。常数值通常直接置于程序代码内部。这样做是安全的因为它们永远都不会改变。有的常数需要严格地保护所以可考虑将它们置入只读存储器ROM
(6) 非RAM 存储。若数据完全独立于一个程序之外则程序不运行时仍可存在并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象对象会变成字节流通常会发给另一台机器。而对于固定对象对象保存在磁盘中。即使程序中止运行它们仍可保持自己的状态不变。对于这些类型的数据存储一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要甚至能将它们恢复成普通的、基于RAM的对象。Java 1.1 提供了对Lightweight persistence 的支持。未来的版本甚至可能提供更完整的方案
<!-- Special Case: Primitive Types -->
### 基础类型的存储
Special Case: Primitive Types
One group of types that youll often use gets special treatment. You can
think of these as “primitive” types. The reason for the special
treatment is that creating an object with new—especially a small,
@@ -187,7 +137,11 @@ Character ch = 'x';
and back:
char c = ch;
The reasons for wrapping primitives are shown in a later chapter.
High-Precision Numbers
<!-- High-Precision Numbers -->
### 高精数值的存储
Java includes two classes for performing high-precision arithmetic:
BigInteger and BigDecimal. Although these fit approximately
the same category as the “wrapper” classes, neither one has a
@@ -204,7 +158,10 @@ information during operations.
BigDecimal is for arbitrary-precision fixed-point numbers; you can
use these for accurate monetary calculations, for example.
Consult the JDK documentation for details about these two classes.
Arrays in Java
<!-- Arrays in Java -->
### 数组的存储
Many programming languages support some kind of array. Using
arrays in C and C++ is perilous because those arrays are only blocks of
memory. If a program accesses the array outside of its memory block
@@ -230,6 +187,10 @@ initialization by zeroing the memory for that array.
Arrays are covered in detail later in the book, and specifically in the
Arrays chapter.
[^1]: 脚注预留
[^2]: 脚注预留
[^3]: 脚注预留
<!-- Comments -->
## 代码注释