在本章,我们将看到 Java 程序的基本组成部分,并体会到在 Java 中(几乎)一切都是对象。
用引用操纵对象
尽管将一切都看作对象,但操纵的标识符实际上是对象的一个 引用(reference)
。可以将这一情形想象成用遥控器(引用)来操纵电视机(对象)。此外,即使没有电视机,遥控器亦可独立存在,也就是说,拥有一个引用,并不一定需要有一个对象与它相关联。1
2
3String s1; //仅仅只创建了一个引用
String s2 = new String("hello"); //创建一个引用并与一个新的对象相关联
必须由你创建所有对象
一旦创建了一个引用,就希望它能与一个新的对象相关联,通常用 new
操作符来实现。
存储到什么地方
一般有五个不同的地方可以存储数据:
- 寄存器(
Registers
):这是最快的存储区,位于处理器内部 - 堆栈(
The stack
):速度仅次于寄存器,位于通用RAM
(随机访问存储器)中。存储在堆栈内的所有项必须知道确切的生命周期,一般将对象的引用存储于堆栈中 - 堆(
The heap
):一种通用的内存池(也位于RAM
区),用于存放所有的 Java 对象 - 常量存储(
Constant storage
):一般直接存放于程序代码内部。在嵌入式系统中,可以选择存放在ROM
(只读存储器)中 - 非
RAM
存储(Non-RAM storage
):数据完全存活于程序之外,例如流对象
和持久化对象
。在流对象中,对象转化成字节流,发送给另一台机器。在持久化对象中,对象被存放于磁盘上。这种存储方式,可以在需要时,将数据恢复成常规的、基于RAM
的对象。
特例:基本类型
用 new
创建一个对象(特别是小的,简单的变量),往往不是很有效。对于这一系列的类型,称之为基本类型。Java 不用 new
来创建一个并非引用的自动变量,而是直接存储值,并且置于堆栈中。
Java 要确定每种基本类型所占存储空间的大小,并且不会随着机器硬件架构的变化而变化。这种不变性,也是 Java 编写的程序更具可移植性的原因之一。
基本类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
---|---|---|---|---|
$boolean$ | $-$ | $-$ | $-$ | $Boolean$ |
$char$ | $16 \; bits$ | $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$ | $IEEE \; 754$ | $IEEE \; 754$ | $Float$ |
$double$ | $64 \; bits$ | $IEEE \; 754$ | $IEEE \; 754$ | $Double$ |
$void$ | $-$ | $-$ | $-$ | $Void$ |
所有数据类型都有正负号,所以不要去寻找无符号的数据类型。boolean
类型所占存储空间大小没有明确指定,仅定义为能够取字面值 true
或 false
。
基本类型具有包装器类,可以在堆中创建一个非基本对象。1
2
3
4Character character = new Character('x');
Character ch = 'X'; //自动包装,将基本类型转换成包装器类型
char c = ch; //也可以反向转换
Java 提供了两个用于高精度计算的类:BigInteger
,BigDecimal
。
Java 中的数组
当创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会自动被初始化为一个特定的值,该值拥有自己的关键字 null
。
永远不需要销毁对象
大多数过程型语言都有 作用域(scope)
的概念。作用域决定了在其内定义的变量名的可见性和生命周期。尽管以下代码在 C 中是合法的,但是在 Java 中不能这样书写。1
2
3
4int x = 12;
{
int x = 96; // Variable 'x' is already defined in the scope
}
在以下代码中,在作用域外无法访问这个对象,但是这个对象仍继续占据内存空间。Java 主要使用 垃圾回收器
来监视用 new
创建的所有对象,并辨别那些不会再被引用的对象。随后,释放这些对象的内存空间,以便供其他新的对象使用。1
2
3
4{
String s = new String("hello");
}
System.out.println(s); // Cannot resolve symbol 's'
创建新的数据类型:类
一旦定义了一个类,就可以在类中设置两种类型的元素:字段
(数据成员)和 方法
(成员函数)。若类的某个字段是基本数据类型,即使没有进行初始化,Java 也会确保它获得一个默认值。
基本类型 | 默认值 |
---|---|
boolean | false |
char | ‘\u0000’ (null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
上述确保初始化只适用于 类的字段
,并不适用于 局部变量
。1
2int x;
System.out.println(x); // Variable 'x' might not have been initialized
方法、参数和返回值
方法的基本组成部分包括:名称,参数,返回值和方法体。除了某些特殊数据类型,通常方法参数传递的是对象的引用。
构建一个 Java 程序
在每个程序文件的开头,必须声明 import
语句,以便引入在文件代码中需要用到的额外类。注意,在这里说额外类,是因为有一个特定类会自动被导入到每一个 Java 文件中:java.lang
。
注释
有三种注释的方式:1
2
3
4
5
6
7
8
9/* This is a comment
* that continues
* across lines
*/
/* This is a comment that
continues across lines */
// This is a one-line comment
通过 javadoc
可以生成良好的程序文档,以 HTML 的形式展现。所有的 javadoc
命令都只能在 /**
注释中出现,以 */
结束,文档标签以 @
字符开头。例如:1
2
3
4/**
*
* @param args
*/
编码风格
类名的首字母要大写,标识符的第一个字母采用小写,例如:1
2
3
4
5
6
7
8class AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors;
void changeTheHueOfTheColor(int newHue) {
}
}