类的特性
1.类声明只是创建一个模板(或类型描述),并不会创建一个实际的对象。
声明对象:
Box mybox = new Box();
这个语句执行后,mybox就是Box的一个实例了。因此,它将具有“物理的”真实性。
要获得一个类的对象需要两步。第一步,你必须声明该类类型的一个变量,这个变量没有定义一个对象。实际上,它只是一个能够引用对象的简单变量。第二步,该声明要创建一个对象的实际的物理拷贝,并把对于该对象的引用赋给该变量。这是通过使用new运算符实现的。new运算符为对象动态分配(即在运行时分配)内存地址,并返回对它的一个引用。这个引用或多或少的是new分配给对象的内存地址。然后这个引用被存储在该变量中。这样,在Java中,所有的类对象都必须动态分配。
Box mybox;
mybox = new Box();
第一行声明了mybox,把它作为对于Box类型的对象的引用。当本句执行后,mybox包含的值为null,表示它没有引用对象。这时任何引用mybox的尝试都将导致一个编译错误。
第二行创建了一个实际的对象,并把对于它的引用赋给mybox。现在,你可以把mybox作为Box的对象来使用。但事实上,mybox仅仅保存实际的Box对象的内存地址。
2.深入new运算符
new运算符动态地为一个对象分配地址。通用格式如下
class-var = new classname();
new运算符是在运行期间为对象分配内存。这样做的好处是你的程序在运行期间可以创建它所需要的内存。但是,内存是有限的,因此new有可能由于内存不足而无法给一个对象分配内存。如果出现这种情况,就会发生运行时异常。
为什么对整数或字符这样的简单变量不使用new运算符?
Java的简单类型不是作为对象实现的。出于效率的考虑,它们只作为“常规”变量实现的。对象由很多特性和属性,使Java对对象的处理不同于简单类型。由于对处理对象和处理简单类型的开销不同,Java能更高效地实现简单类型。对于那些需要完全对象类型的情况下,简单类型的对象版本也可用。
3.给对象引用变量赋值
Box b1 = new Box();
Box b2 = b1;
b1和b2引用同样的对象。将b1赋值给b2并没有分配任何内存或对原对象做任何部分的拷贝。由于它们是同一个对象,因此通过变量b2对对象的改变也将影响b1所对应的对象。
b1和b2除引用同一个对象外,没有任何其他的关系。
b1 = null;
这样的复制仅仅使b1脱离(unhook)初始化对象,而没有影响对象或b2.
Tips: 当你将一个对象引用赋值给另一个对象引用时,你并没有创建该对象的一个拷贝,而是仅仅对引用的一个拷贝。
4.垃圾回收
Java自动处理重新分配内存的办法:当一个对象的引用不存在时,则该对象被认为是不再需要的,它所占用的内存就被释放掉。垃圾回收只在你的程序执行过程中偶尔发生。它不会因为一个或几个存在的对象不再被使用而发的。Java不同的运行时刻会产生各种不同的垃圾回收方法。
5.finalize()方法
如果一个对象正在处理的是非Java资源,如文件句柄或windows字符字体,这时你要确认在一个对象被撤销以前要保证这些资源被释放。为处理这样的状况,Java提供了被称为收尾(finalization)的机制。使用该机制可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。
要给一个类增加收尾(finalizer),你只要定义finalize()方法即可。Java回收该类的一个对象时,就会调用这个方法。在finalize方法中,你要指定在一个对象被撤销前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之前,Java运行系统调用该对象的finalize()方法。