2.一切都是对象
前言
1.c与c++的关系:c++是c的超集,c++有c的特性,但是c没有c++的特性
2.java与c++的关系:都是杂合(比c语言复杂的)语言,允许采用多种编程风格
总结:
如何学好c++/java:先使自己能够有面向对象的思维方式
一.一切都是对象
1.用句柄操作对象
摘自java编程思想一书:
每种编程语言都有自己的数据处理方式。有些时候,程序员必须时刻留意准备处理的是什么类型。您曾利用
一些特殊语法直接操作过对象,或处理过一些间接表示的对象吗( C 或 C++里的指针)?
所有这些在 Java 里都得到了简化,任何东西都可看作对象。因此,我们可采用一种统一的语法,任何地方均
可照搬不误。但要注意,尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“句柄”
( Handle)。在其他 Java 参考书里,还可看到有的人将其称作一个“引用”,甚至一个“指针”。可将这一
情形想象成用遥控板(句柄)操纵电视机(对象)。只要握住这个遥控板,就相当于掌握了与电视机连接的
通道。但一旦需要“换频道”或者“关小声音”,我们实际操纵的是遥控板(句柄),再由遥控板自己操纵
电视机(对象)。如果要在房间里四处走走,并想保持对电视机的控制,那么手上拿着的是遥控板,而非电
视机。
此外,即使没有电视机,遥控板亦可独立存在。也就是说,只是由于拥有一个句柄,并不表示必须有一个对
象同它连接。所以如果想容纳一个词或句子,可创建一个 String 句柄:
String s;
但这里创建的只是句柄,并不是对象。若此时向s 发送一条消息,就会获得一个错误(运行期)。这是由于
实际并未与任何东西连接(即“没有电视机”)。因此,一种更安全的做法是:创建一个句柄时,记住无
论如何都进行初始化:
String s = "asdf";
然而,这里采用的是一种特殊类型:字串可用加引号的文字初始化。通常,必须为对象使用一种更通用的初
始化类型。
分析:
句柄其实就是引用/指针,
String a="123"; 该变量a就是在栈区存放着一个指向字符对象“123”的引用,也就是首指针(这个"123"对象存放在String池,以后会专门讲解java六大内存存储区),如果该变量a没有赋值"123"(没有进行初始化),那么这个变量a还是一直在引用的,只不过是未指向任何对象。
注意:“一直引用”:尽管变量a没有进行任何赋值(没有在内存中开辟空间存放对象),但是由于一直在引用,所以jvm并未释放该引用(以后会专门讲解java六大内存存储区)
与String b=null;不同的是,变量b也是一直在引用,但是它所指向的对象其实就是一个空对象。
2.所有对象都必须创建才能使用
摘自java编程思想一书:
创建句柄时,我们希望它同一个新对象连接。通常用new 关键字达到这一目的。 new 的意思是:“把我变成
这些对象的一种新类型”。所以在上面的例子中,可以说:
String s = new String("asdf");
它不仅指出“将我变成一个新字串”,也通过提供一个初始字串,指出了“如何生成这个新字串” 。
当然,字串( String)并非唯一的类型。 Java 配套提供了数量众多的现成类型。对我们来讲,最重要的就是
记住能自行创建类型。事实上,这应是 Java 程序设技的一项基本操作,是继续本书后余部分学习的基础。
2.1保存到什么地方(简略说明:java六大内存存储区)
摘自java编程思想一书:
程序运行时,我们最好对数据保存到什么地方做到心中有数。特别要注意的是内存的分配。有六个地方都可
以保存数据:
(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.2特殊情况:主要类型
摘自java编程思想一书:
有一系列类需特别对待;可将它们想象成“基本”、“主要”或者“主”( Primitive)类型,进行程序设计
时要频繁用到它们。之所以要特别对待,是由于用 new 创建对象(特别是小的、简单的变量)并不是非常有
效,因为 new 将对象置于“堆”里。对于这些类型, Java 采纳了与 C 和 C++相同的方法。也就是说,不是用
new 创建变量,而是创建一个并非句柄的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更
高效地存取。
Java 决定了每种主要类型的大小。就象在大多数语言里那样,这些大小并不随着机器结构的变化而变化。这
种大小的不可更改正是 Java 程序具有很强移植能力的原因之一。
--------------------------------------------------------------------------
主类型 大小 最小值 最大值 封装器类型
boolean 1 位 - - Boolean
char 16 位 Unicode 0 Unicode 2 的 16 次方-1 Character
byte 8 位 -128 +127 Byte(注释①)
short 16 位 -2 的 15 次方 +2 的 15 次方-1 Short(注释①)
int 32 位 -2 的 31 次方 +2 的 31 次方-1 Integer
long 64 位 -2 的 63 次方 +2 的 63 次方-1 Long
float 32 位 IEEE754 IEEE754 Float
double 64 位 IEEE754 IEEE754 Double
Void - - - Void(注释①)
①:到 Java 1.1 才有, 1.0 版没有。
--------------------------------------------------------------------------
数值类型全都是有符号(正负号)的,所以不必费劲寻找没有符号的类型。
主数据类型也拥有自己的“封装器”( wrapper)类。这意味着假如想让堆内一个非主要对象表示那个主类
型,就要使用对应的封装器。例如:
char c = 'x';
Character C = new Character('c');
也可以直接使用:
Character C = new Character('x');
这样做的原因将在以后的章节里解释。
可参考:java自动装箱和拆箱详解
1. 高精度数字
Java 1.1 增加了两个类,用于进行高精度的计算: BigInteger 和 BigDecimal。尽管它们大致可以划分为
“封装器”类型,但两者都没有对应的“主类型”。
这两个类都有自己特殊的“方法”,对应于我们针对主类型执行的操作。也就是说,能对int 或 float 做的
事情,对 BigInteger 和 BigDecimal 一样可以做。只是必须使用方法调用,不能使用运算符。此外,由于牵
涉更多,所以运算速度会慢一些。我们牺牲了速度,但换来了精度。
BigInteger 支持任意精度的整数。也就是说,我们可精确表示任意大小的整数值,同时在运算过程中不会丢
失任何信息。
BigDecimal 支持任意精度的定点数字。例如,可用它进行精确的币值计算。
至于调用这两个类时可选用的构建器和方法,请自行参考联机帮助文档。
2.3java数组
摘自java编程思想一书:
几乎所有程序设计语言都支持数组。在 C 和 C++里使用数组是非常危险的,因为那些数组只是内存块。若程
序访问自己内存块以外的数组,或者在初始化之前使用内存(属于常规编程错误),会产生不可预测的后果
(注释②)。
②:在 C++里,应尽量不要使用数组,换用标准模板库( Standard TemplateLibrary)里更安全的容器。
Java 的一项主要设计目标就是安全性。所以在 C 和 C++里困扰程序员的许多问题都未在 Java 里重复。一个
Java 可以保证被初始化,而且不可在它的范围之外访问。由于系统自动进行范围检查,所以必然要付出一些
代价:针对每个数组,以及在运行期间对索引的校验,都会造成少量的内存开销。但由此换回的是更高的安
全性,以及更高的工作效率。为此付出少许代价是值得的。
创建对象数组时,实际创建的是一个句柄数组。而且每个句柄都会自动初始化成一个特殊值,并带有自己的
关键字: null(空)。一旦 Java 看到 null,就知道该句柄并未指向一个对象。正式使用前,必须为每个句
柄都分配一个对象。若试图使用依然为 null的一个句柄,就会在运行期报告问题。因此,典型的数组错误在
Java 里就得到了避免。
也可以创建主类型数组。同样地,编译器能够担保对它的初始化,因为会将那个数组的内存划分成零。
数组问题将在以后的章节里详细讨论。
关于数组详解可参考:http://lavasoft.blog.51cto.com/62575/183878
二.绝对不要清楚对象
一般我们不需要手动清理,java会自动清理的
2.1作用域
请看书
2.2对象的作用域
请看书
三 新建数据类型:类
请看书
四 方法、自变量和返回值
请看书,另外请注意:(关于传值和传引用的区别:)
传值就是你改变这个值,不会改变原值。例如
int a=1;
把a作为参数经过方法调用,在方法中改变a的值如。
a=2;
在方法中a是变成2了。
但是在外面a还是1。.
如果是传引用,值是会变的。
例如这样
public class Test { public void test(List list){ list.remove(0); list.add("b"); } public static void main(String[] args) { String a="123"; List list=new ArrayList(); list.add(a); new Test().test(list); System.out.println(list.get(0)); } }传对象的都是传引用。

浙公网安备 33010602011771号