05 清理和初始化

清理和初始化

默认构造器

只要定义了一个构造器,编译器就不会帮我们自动创建默认构造器了。

this

1
2
3
String a = new String();
String b = new String();
a.toString();

如何确定调用类中的方法的对象是哪一个?

实际上,a.toString()的真实调用时这样的:String(a)。
编译器会暗自把“所操作的对象的引用”作为第一个参数传递给peel()。

使用this有什么用?

  1. 构造器中调用其它构造器只能使用this(参数),这时候的this的含义不表示对象的引用了。不能使用两次。
  2. 区别参数和成员对象。
  3. 返回当前的对象,this的类型是实际运行时类型。

注意:static方法不能使用this

垃圾回收

一般来说,JAVA中的GC可以帮我们回收无用对象占有的资源,但也有一些特殊情况:垃圾回收期只回收使用new关键字分配的内存,通过其他方式获取的“特殊”内存区域,GC不知道如何回收。

如何应对这种情况?

JAVA提供了finalize()方法,垃圾回收器在回收对象前会调用这个方法。

finalize()这和C++中的析构函数一样吗?

C++中的对象可以在栈中,也可以在堆中。在栈中的对象生命周期是当前方法的作用域,离开这个作用域“{}”,就会调用析构函数,并且回收内存。在堆中的对象(使用new)需要使用delete来销毁,并且在回收内存也会调用析构函数。那么这里有两点:

  1. 对象内存一定会被回收。
  2. 析构函数正常情况下都会被调用。

    C++中没有被回收的内存会造成内存泄漏,一直到下次重启这部分占用的内存才会消除。

由此我们可以分析出java中的垃圾回收和finalize()的区别了:

  1. 对象不一定会被回收,即便是GC开始回收了。
  2. 因此finalize()也不一定会被调用,因此在finalize()中处理关闭资源等普通的清理操作是没有意义的。

    和C++还有不一样的一点是,finalize()是不能被直接调用的。

那么finalize()有什么用呢?

我们说垃圾回收是和内存不足了有关的,那么也就意味着:

  1. 只有内存不足的时候才会调用finalize(),也就意味着,在finalize()中最好也是处理内存相关的清理操作,而不是关闭资源等普通的清理操作。

需要在finalize()里处理的内存清理操作是什么?

这种情况主要发生在“本地方法”的情况下,即在JAVA中调用了非JAVA的方法,这部分方法申请的内存需要使用free()来释放,因此在finalize()中调用free()方法。

初始化

变量在使用前必须初始化,否则会出现程序错误。
成员变量会有一个默认值,局部变量需要手动赋值。

初始化的顺序是怎样的?

感觉就是分为类的初始化和对象的初始化。

  1. 当首次调用静态方法,静态字段,构造器(可以看成静态方法)时,检查Class文件,若未发现,开始类初始化:加载.class文件,然后按顺序执行所有的静态初始化。
  2. 之后就不会再做类初始化了,当调用new()的时候执行对象的初始化:先在堆上分配空间,这块空间会被清零,也就是开始赋默认值,执行非静态的初始化。
  3. 执行构造器。
  4. 将引用指向这个地址(这一步有可能重排序)

本文标题:05 清理和初始化

文章作者:Sun

发布时间:2018年11月14日 - 20:11

最后更新:2018年12月12日 - 16:12

原始链接:https://sunyi720.github.io/2018/11/14/THING IN JAVA/05 清理和初始化/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。