第二章 一切都是对象
尽管Java是基于C++的,但是相比之下,Java是一种更“纯粹”的面向对象程序设计语言。
因为C++是C的一个超集,所以势必包括许多C语言不具备的特性,这些特性使C++在某些方面显得过于复杂。
2.1用引用操纵对象
每种编程语言都有自己的操纵内存中元素的方式。有时候,程序员必须注意将要处理的数据是什么类型的。你是直接操纵元素,还是用某种给予特殊语法的间接表示(C、C++是用指针)来操纵对象?
创建一个String引用
1 | String s; |
但这里创建的只是引用,并不是对象。如果此时向s发送一个信息,就会返回一个运行时错误。因为s并没有被初始化。
1 | String s = "songyaxu"; |
这里用到了一个Java语言的特性,字符串可以用带引号的文本初始化。通常,必须对对象采用一种更通用的初始化方法。
2.2必须由你创建所有对象
一旦创建了一个引用,就希望它能与一个新的对象相关联。通常使用new来实现这个目的。
1 | String s = new String("songyaxu"); |
当然Java也提供了大量的过剩的现成类型。
2.2.1存储到什么地方
程序运行时,对象是怎样进行放置安排的呢?特别是内存是怎样分配的呢?对这些方面的了解会对你有很大的帮助。有5个不同的地方可以存储数据:
序号 | 名称 | 说明 |
---|---|---|
1 | 寄存器 | 这时最快的存储区,它位于处理器内部,但是寄存器的数量有限,所以寄存器根据需求进行分配。 |
2 | 堆栈 | 位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。Java系统必须知道存储在堆栈内所以项的生命周期,这一约束限制了程序的灵活性,所以Java数据存储于对战中,特别是对象引用,但Java对象并不存储于其中。 |
3 | 堆 | 一种通用的内存池(位于RAM区)用于存放Java所以对象,对不同于堆栈的好处是:编译器不需要知道存储的数据的具体生命周期。 |
4 | 常量存储 | 常量值直接存储在程序代码内部,这样做是安全的,因为他们永远不会被改变 |
5 | 非RAM存储 | 如果数据完全存活于程序外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在,例子是流对象和持久化对象 |
2.2.2特例:基本类型
在程序中常用到的基本类型,它们需要特殊处理。
Java要确定每种基本类型所占存储空间的大小。它们的大小并不像其他大多数语言那样随机器硬件架构的变化而变化。这种所占存储空间大小的不变性是Java程序比其他大多数语言编写的程序更具有可移植性的原因之一。
基本类型 | 大小 | 最小值 | 最大值 | 包装类型 |
---|---|---|---|---|
boolean | - | - | - | Boolean |
char | 16-bit | Unicode 0 | Unicode 2^16-1 | Character |
byte | 8 bits | -128 | +127 | Byte |
short | 16 bits | -2^15 | +2^15-1 | Short |
int | 32 bits | -2^31 | +2^31-1 | Integer |
long | 64 bits | -2^63 | +2^63-1 | Long |
float | 32 bits | IEEE754 | IEEE754 | Float |
double | 64 bits | IEEE754 | IEEE754 | Double |
void | - | - | - | Void |
所有数值类型都有正负号,所以不要去寻找无符号的数值类型。
基本类型的包装器类,使得可以在堆中创建一个非基本对象,用来表示对的基本类型。
1 | char c = 'x'; |
也可以是
1 | Charater ch = new Charater('x'); |
而且Java SE5的自动包装功能将自动地将基本类型转换为包装类型,并可以反向转换
1 | Character ch = 'x'; |
高精度数字
Java提供了两个用于高精度计算的类:BigInteger、BigDecimal.他们属于包装类型范畴,但是没有基本类型。
BigInteger支持任意精度的整数。也就是说,在运算中,可以表示任意大小的整数,而不会丢失任何信息。
BigDecimal支持任何精度的定点数,可以进行货币运算。
2.2.3Java中的数组
Java主要的目标之一是安全性。Java确保数组会被初始化,而不能在它的范围之外被访问。这种检查是以每个数组上少量的内存开销及运行时的下标检查为代价的。但由此换来的是安全性和效率的提高,因此付出的代价是值得的。