JAVA编程思想学习 --- 第二章 (一切都是对象)

1.程序运行时,我们数据保存的地方
    (1) 寄存器这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。
    (2) 堆栈驻留于常规 RAM(随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时, Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存
在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活性,所以尽管有些 Java 数据要保存在堆栈里—— 特别是对象句柄,但 Java 对象并不放到其中。
    (3) 一种常规用途的内存池(也在 RAM 区域),其中保存了 Java 对象。和堆栈不同,“内存堆”或“堆”( Heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new 命
令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!
    (4) 静态存储这儿的“静态”( Static)是指“位于固定位置”(尽管也在 RAM 里)。程序运行期间,静态存储的数据将随时等候调用。可用static 关键字指出一个对象的特定元素是静态的。但 Java 对象本身永远都不会置入静态存储空间。
    (5) 常数存储常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入只读存储器( ROM)。
    (6) 非 RAM 存储若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复成普通的、基于 RAM 的对象。 Java 1.1 提供了对 Lightweight persistence 的支持。未来的版本甚至可能提供更完整的方案


2.特殊情况:基本数据类型
    有一系列类需特别对待;可将它们想象成“基本”、“主要”或者“主”( Primitive)类型,进行程序设计时要频繁用到它们。之所以要特别对待,是由于用 new 创建对象(特别是小的、简单的变量)并不是非常有效,因为 new 将对象置于“堆”里。对于这些类型, Java 采纳了与 C 和 C++相同的方法。也就是说,不是用new 创建变量,而是创建一个并非句柄的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更高效地存取
    Java 决定了每种主要类型的大小。就象在大多数语言里那样,这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是 Java 程序具有很强移植能力的原因之一。

     下面是基本数据类型的大小,最大值,最小值,封装类型,以及默认值等
   JAVA编程思想学习 --- 第二章 (一切都是对象)JAVA编程思想学习 --- 第二章 (一切都是对象)


3.Java的数组
     创建对象数组时,实际创建的是一个句柄数组。而且每个句柄都会自动初始化成一个特殊值,并带有自己的 关键字: null(空)。一旦 Java 看到 null,就知道该句柄并未指向一个对象。正式使用前,必须为每个句 柄都分配一个对象。若试图使用依然为 null 的一个句柄,就会在运行期报告问题。因此,典型的数组错误在 Java 里就得到了避免。
     也可以创建主类型数组。同样地,编译器能够担保对它的初始化,因为会将那个数组的内存划分成零。



4.对象的字段和方法
     定义一个类时(我们在 Java 里的全部工作就是定义类、制作那些类的对象以及将消息发给那些对象),可在自己的类里设置两种类型的元素数据成员(有时也叫“字段”)以及成员函数(通常叫“方法”)。其 中,数据成员是一种对象(通过它的句柄与其通信),可以为任何类型。它也可以是主类型(并不是句柄) 之一。如果是指向对象的一个句柄,则必须初始化那个句柄,用一种名为“构建器”(第4 章会对此详述)的特殊函数将其与一个实际对象连接起来(就象早先看到的那样,使用new 关键字)。但若是一种主类型, 则可在类定义位置直接初始化(正如后面会看到的那样,句柄亦可在定义位置初始化)。每个对象都为自己的数据成员保有存储空间;数据成员不会在对象之间共享

     我们创建类时会指出那个类的对象的外观与行为。除非用new 创建那个类的一个对象,否则实际上并 未得到任何东西。只有执行了 new 后,才会正式生成数据存储空间,并可使用相应的方法。

     一旦将变量作为类成员使用,就要特别注意由 Java 分配的默认值。这样做可保证主类型的成员变量肯定得到 了初始化( C++不具备这一功能),可有效遏止多种相关的编程错误。 然而,这种保证却并不适用于“局部”变量—— 那些变量并非一个类的字段。所以,假若在一个函数定义中
写入下述代码:
    int x;
     那么 x 会得到一些随机值(这与 C 和 C++是一样的),不会自动初始化成零。我们责任是在正式使用x 前分 配一个适当的值。如果忘记,就会得到一条编译期错误,告诉我们变量可能尚未初始化。这种处理正是 Java 优于 C++的表现之一。许多 C++编译器会对变量未初始化发出警告,但在 Java 里却是错误。




5.类名字的可见性
     在所有程序设计语言里,一个不可避免的问题是对名字或名称的控制假设您在程序的某个模块里使用了一个名字,而另一名程序员在另一个模块里使用了相同的名字。此时,如何区分两个名字,并防止两个名字互 相冲突呢?这个问题在 C 语言里特别突出。因为程序未提供很好的名字管理方法。 C++的类(即 Java 类的基 础)嵌套使用类里的函数,使其不至于同其他类里的嵌套函数名冲突。然而, C++仍然允许使用全局数据以及 全局函数,所以仍然难以避免冲突。为解决这个问题, C++用额外的关键字引入了“命名空间”的概念。
     由于采用全新的机制,所以 Java 能完全避免这些问题。为了给一个库生成明确的名字,采用了与Internet 域名类似的名字。事实上, Java 的设计者鼓励程序员反转使用自己的 Internet 域名,因为它们肯定是独一 无二的。由于我的域名是 BruceEckel.com,所以我的实用工具库就可命名为
com.bruceeckel.utility.foibles。反转了域名后,可将点号想象成子目录。 在 Java 1.0 和 Java 1.1 中,域扩展名 com, edu, org, net 等都约定为大写形式。所以库的样子就变成: COM.bruceeckel.utility.foibles。然而,在 Java 1.2 的开发过程中,设计者发现这样做会造成一些问题。 所以目前的整个软件包都以小写字母为标准。
     Java 的这种特殊机制意味着所有文件都自动存在于自己的命名空间里。而且一个文件里的每个类都自动获得 一个独一无二的标识符(当然,一个文件里的类名必须是唯一的)。




6.使用其他的组件(其他类)
     一旦要在自己的程序里使用一个预先定义好的类,编译器就必须知道如何找到它。当然,这个类可能就在发 出调用的那个相同的源码文件里。如果是那种情况,只需简单地使用这个类即可—— 即使它直到文件的后面 仍未得到定义。 Java 消除了“向前引用”的问题,所以不要关心这些事情。
     但假若那个类位于其他文件里呢?您或许认为编译器应该足够“联盟”,可以自行发现它。但实情并非如 此。假设我们想使用一个具有特定名称的类,但那个类的定义位于多个文件里。或者更糟,假设我们准备写
     一个程序,但在创建它的时候,却向自己的库加入了一个新类,它与现有某个类的名字发生了冲突。 为解决这个问题,必须消除所有潜在的、纠缠不清的情况。为达到这个目的,要用import 关键字准确告诉 Java 编译器我们希望的类是什么。 import 的作用是指示编译器导入一个“包” —— 或者说一个“类库”(在 其他语言里,可将“库”想象成一系列函数、数据以及类的集合。但请记住, Java 的所有代码都必须写入一 个类中)。
     大多数时候,我们直接采用来自标准 Java 库的组件(部件)即可,它们是与编译器配套提供的。使用这些组 件时,没有必要关心冗长的保留域名;举个例子来说,只需象下面这样写一行代码即可:
import java.util.Vector;
     它的作用是告诉编译器我们想使用 Java 的 Vector 类。然而, util 包含了数量众多的类,我们有时希望使用 其中的几个,同时不想全部明确地声明它们。 为达到这个目的,可使用“ *”通配符。如下所示:
import java.util.*;
     需导入一系列类时,采用的通常是这个办法。应尽量避免一个一个地导入类。


7.static关键字
     通常,我们创建类时会指出那个类的对象的外观与行为。除非用new 创建那个类的一个对象,否则实际上并 未得到任何东西。只有执行了 new 后,才会正式生成数据存储空间,并可使用相应的方法。
     但在两种特殊的情形下,上述方法并不堪用。一种情形是只想用一个存储区域来保存一个特定的数据—— 无 论要创建多少个对象,甚至根本不创建对象。另一种情形是我们需要一个特殊的方法,它没有与这个类的任 何对象关联。也就是说,即使没有创建对象,也需要一个能调用的方法。为满足这两方面的要求,可使用 static(静态)关键字一旦将什么东西设为 static,数据或方法就不会同那个类的任何对象实例联系到一 起。
     它意味着一个特定的方法没有 this。我们不可从一个 static 方法内部发出对非 static 方法的调用,尽管反过来说是可以的。 而且在没有任何对象的前提下,我们可针对类本身发出对一个 static 方法的调用。事实上,那正是 static 方法最基本的意义。它就好象我们创建一个全局函数的等价物(在C 语言中)。除了全局函数不允许在 Java 中使用以外,若将一个 static 方法置入一个类的内部,它就可以访问其他 static 方法以及 static 字段。




8.public static void main(String[] args)的解释  
     类名与文件是一样的若想现在这样创建一个独立的程序,文件中的一个类必须与文件同名(如果没这样 做,编译器会及时作出反应)。类里必须包含一个名为 main()的方法,形式如下:
public static void main(String[] args) {
     其中,关键字“ public”意味着方法可由外部世界调用(第 5 章会详细解释)。main()的自变量是包含了 String 对象的一个数组args 不会在本程序中用到,但需要在这个地方列出,因为它们保存了在命令行调用 的自变量。



9.注释和嵌入文档
     Java 里有两种类型的注释。第一种是传统的、 C 语言风格的注释,是从 C++继承而来的。这些注释用一个 “ /*”起头,随后是注释内容,并可跨越多行,最后用一个“ */”结束。两种注释示例
第一种:
// 这是一条单行注释

第二种
/* 这是
* 一段注释,
* 它跨越了多个行
*/


     对于 Java 语言,最体贴的一项设计就是它并没有打算让人们为了写程序而写程序—— 人们也需要考虑程序的 文档化问题。对于程序的文档化,最大的问题莫过于对文档的维护。若文档与代码分离,那么每次改变代码 后都要改变文档,这无疑会变成相当麻烦的一件事情。解决的方法看起来似乎很简单:将代码同文档“链 接”起来。为达到这个目的,最简单的方法是将所有内容都置于同一个文件。然而,为使一切都整齐划一, 还必须使用一种特殊的注释语法,以便标记出特殊的文档;另外还需要一个工具,用于提取这些注释,并按 有价值的形式将其展现出来。这些都是 Java 必须做到的。
     用于提取注释的工具叫作 javadoc。它采用了部分来自 Java 编译器的技术,查找我们置入程序的特殊注释标 记。它不仅提取由这些标记指示的信息,也将毗邻注释的类名或方法名提取出来。这样一来,我们就可用最 轻的工作量,生成十分专业的程序文档。
     javadoc 输出的是一个 HTML 文件,可用自己的 Web 浏览器查看。该工具允许我们创建和管理单个源文件,并 生动生成有用的文档。由于有了 jvadoc,所以我们能够用标准的方法创建文档。而且由于它非常方便,所以 我们能轻松获得所有 Java 库的文档。

@ see :引用其他类

类文档标记:
@version 版本信息
其中,“版本信息”代表任何适合作为版本说明的资料。若在 javadoc 命令行使用了“ -version”标记,就
会从生成的 HTML 文档里提取出版本信息。

@author 作者信息
其中,“作者信息”包括您的姓名、电子函件地址或者其他任何适宜的资料。若在javadoc 命令行使用了“ -
author”标记,就会专门从生成的 HTML 文档里提取出作者信息。

方法文档标记
@param 参数名 说明
其中,“参数名”是指参数列表内的标识符,而“说明”代表一些可延续到后续行内的说明文字。一旦遇到
一个新文档标记,就认为前一个说明结束。可使用任意数量的说明,每个参数一个。

@return 说明
其中,“说明”是指返回值的含义。它可延续到后面的行内。

@exception 完整类名 说明
其中,“完整类名”明确指定了一个违例类的名字,它是在其他某个地方定义好的。而“说明”(同样可以
延续到下面的行)告诉我们为什么这种特殊类型的违例会在方法调用中出现。

@deprecated
这是 Java 1.1 的新特性。该标记用于指出一些旧功能已由改进过的新功能取代。该标记的作用是建议用户不
必再使用一种特定的功能,因为未来改版时可能摒弃这一功能。若将一个方法标记为@deprecated,则使用该
方法时会收到编译器的警告。


10.编码样式
     一个非正式的 Java 编程标准是大写一个类名的首字母。若类名由几个单词构成,那么把它们紧靠到一起(也 就是说,不要用下划线来分隔名字)。此外,每个嵌入单词的首字母都采用大写形式。例如:
class AllTheColorsOfTheRainbow { // ...}
     对于其他几乎所有内容:方法、字段(成员变量)以及对象句柄名称,可接受的样式与类样式差不多,只是 标识符的第一个字母采用小写。



最近在看JAVA编程思想(第四版)这本书,将书中的一些知识点容易遇到或者混淆的概念记录下来,只是作为备忘,希望也能帮到需要的人,特此申明.