Thinking In Java——初始化与清理读书笔记及摘录

使用构造器确保初始化

  1. 从概念上讲,“初始化”与“创建”是彼此独立的。在Java中“初始化”和“创建”是绑定在一起的;
  2. 构造器是一种特殊类型的方法,因为它没有返回值。这与返回值为空(void)明显不同。对于空返回值,尽管方法本身不会自动返回什么,但是仍可选择让它返回别的东西。构造器则不会返回任何东西,虽然new表达式确实是返回对新建对象的引用。

清理:终结处理和垃圾回收

  1. 在c++中,对象一定会被销毁;而Java里的对象却并非总是被垃圾回收。换句话说:对象可能不被垃圾回收,垃圾回收不等于析构;
  2. 只要程序没有濒临储存空间用完的那一刻,对象占用的空间就总也得不释放。如果程序执行结束,并且垃圾回收器一直都没有释放创建的任何对象的储存空间,则随着程序的退出,那些资源也会全部交还给操作系统;

finalize()的用途

finalize()在jdk9开始就被废除,如果想使用finalize()来处理释放资源的情况可以使用try-catch-finally,如果想用finalize()来获取对象被回收的时机可以使用虚引用和引用队列+回调,在jdk12中可以使用System.runFinalization()来强制执行对象中的finalize()用于清理垃圾对象。

“垃圾回收只与内存有关。”使用垃圾回收器的唯一原因是为了回收程序不再是使用的内存。所以对于与垃圾回收有关的任何行为来说,行为也必须和内存及其回收有关。

重写finalize()方法也可以用来最后检查某个对象的正确性,虽然finalize()可能不会被调用,所以这种检查方式并不是十分可靠的。

必须实施清理

无论是“垃圾回收”还是“终结”,都不保证一定会发生。如果JVM并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的。

终结条件

当对某个对象不再感兴趣——也就是它可以被清理了,这个对象应该处于某种状态,使他占用的内存可以被安全释放。只要对象中存在没有被适当清理的部分,程序就存在很隐晦的缺陷。finalize()可以用来最终发现这种情况——尽管它并不总是被调用的。如果某次finalize()使得缺陷被发现,那么就可以据此找出问题所在——这才是人们真正关心的。

成员初始化

Java尽力保证:所有变量使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。

构造器初始化

可以使用构造器来初始化。在运行时刻,可以调用方法或者执行某些动作来确定初值,这为变成带来了更大的灵活性。但要牢记:无法阻止自动初始化的进行,它将在构造器被调用之前发生。

总结一下对象的创建过程,假设有个Dog类:

  1. 即时没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次类型为Dog的对象时(构造器可以看做是静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件;
  2. 然后加载Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载时执行一次;
  3. 当用new Dog()创建对象时,首先将在堆上为Dog对象分配足够的存储空间;
  4. 这块空间会被清零,这就自动地为Dog对象中的所有基本类型数据都设置了默认值(对数字来说是0,对布尔值类型来说也是如此),而引用则被设置为了null;
  5. 执行所有出现于字段定义处的初始化动作;
  6. 执行构造器;
发布了24 篇原创文章 · 获赞 8 · 访问量 1859

猜你喜欢

转载自blog.csdn.net/qq_40462579/article/details/103103514