二、一切都是对象
1、Java程序有五个不同的地方可以存储数据:
寄存器 这是最快的存储区,因为它位于不同于其他存储区的地方----处理器内部。但是寄存器的数量是机器有限的,所以一般是根据需要来进行分配的。我们不能够直接控制寄存器,也不能在程序中感觉到寄存器的存在的任何迹象(另一方面,C和C++允许向编译器建议寄存器的分配方式)。
堆栈 位于通用RAM中,但是通过堆栈指针可以从处理器那里获得直接支持。堆栈指针若乡下移动,则分配新的内存;若向下移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时。Java系统必须知道存储在堆栈中所有项的确切生命周期,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些Java数据存储于堆栈中(基本类型变量和引用),但是Java对象并不存储于其中。
堆 一种通用的内存池(也位于RAM区),用于存放所有的Java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存货多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象的时候,只需要用new写一行简单的代码,当执行这行代码时,会自动在堆那里进行存储分配。当然,为这种灵活性必须要付出相应的代价:用堆进行存储分配和清理可能比用堆栈进行存储分配需要更多的时间。
常量存储 常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分隔离开,所以在这种情况下,可以选择将其存放在ROM中。
非RAM存储 如果数据完全存货在程序之外,那么它可以不受程序的任何控制,在程序没有运行的时候也存在,其中的基本的两个例子就是流对象和持久化对象。在流对象中,对象转化成字节流,通常被发送给另一台机器。在“持久化对象“中,对象被存放在磁盘上,因此,及时程序终止,它们仍可以保持自己的状态。这种存储方式的技巧在于:把对象转化为可以存放在其他媒介上的事物,在需要时,可恢复成常规的,基于RAM的对象,Java提供了对轻量级持久化的支持,而诸如JDBC和Hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。
2.1 特例:基本类型
基本类型是一个并非是引用的“自动”变量。这个变量直接存储“值”,并置于堆栈中,因此更加高效。Java的基本类型所占存储空间大小不随机器硬件架构的变化而变化。这种所占存储空间大小的不变性是Java程序比用其他大多数语言编写的程序更具可移植性的原因之一。
基本类型 | 大小 | 最小值 | 最大值 | 包装器类 |
---|---|---|---|---|
boolean | - | - | - | Boolean |
byte | 8 bits | -128 | +127 | Byte |
char | 16 bits | Unicode 0 | Unicode 216-1 | Character |
short | 16 bits | -215 | +215-1 | Short |
int | 32 bits | -232 | +232-1 | Integer |
float | 32 bits | IEEE754 | IEEE754 | Float |
long | 64 bits | -263 | +263-1 | Long |
double | 64 bits | IEEE754 | IEEE754 | Double |
void | - | - | - | Void |
所有数值类型都有正负号
boolean类型所占存储空间的大小没有明确指定(要看具体虚拟机的实现),仅定义为能够取字面值true或false。
2.2 Java中的数组
2.3 作用域(scope)
1. Java 与 C/C++ 关于作用域的区别:如下,对于Java,非法,而对于 C/C++ 合法。(在 C/C++ 里将一个作用域的变量“隐藏”起来的做法,在Java里是不允许的。因为Java设计者认为这样做会导致程序混乱。
2. Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时,它可以存活于作用域之外。如:
{
String s = new String("a string");
} // End of scope
引用 s
在作用域终点就消失了。然而,s
指向的 String 对象仍继续占据内存空间。
2.4 import 关键字
import关键字指示编译器导入一个包,也就是一个类库(在其他语言中,一个库不仅包含类,还可能包括方法和数据,但是Java中所有的代码都必须写在类里)。
特定类 java.lang
会被自动导入到每一个Java文件中。
2.5 static 关键字
5.1 通过 static 关键字可以满足以下两方面情形的需要:
- 只想为某一特定域分配单一存储空间,而不去考虑空间要创建多少对象,甚至根本就不创建任何对象。
- 希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用这个方法。
有些面向对象语言采用类数据和类方法两个术语,代表那些数据和方法只是作为整个类,而不是类的某个特定对象而存在的。例:
5.2 static 字段
5.3 static 方法
-
static
作用于字段时,会改变数据的创建方式,但作用于方法时,差别却没有那么大。static
方法的一个重要用法就是在不创建任何对象的前提下就可以调用它。这一点对定义main()
方法很重要(所以main()
方法是一个 satic 方法),这个方法是运行一个应用时的入口点。 - 和其它任何方法一样,
static
方法可以创建或使用与其类型相同的被命名对象,因此,static
方法常常拿来做“牧羊人”的角色,负责看护与其隶属同一类型的实例群。 -
static
方法的含义:static
方法就是没有this
的方法。关于static方法内部是否能调用非静态方法:因为没有this
,就没有对象,所以不能直接调用非静态方法,但可以传递一个对象引用到静态方法里,然后通过这个引用(和this
效果相同)来调用非静态方法和访问非静态数据成员。 - 有些人认为
static
方法不是“面向对象”的,因为它们的确具有全局函数的语义;使用static
方法时,由于不存在this
,所以不是通过“向对象发送消息”的方式来完成的。