Java笔记整理:初始化与清理
构造器
构造器没有返回值
方法重载
每个重载方法都有一个独一无二的参数类型列表
如果传入的数据类型小于声明的形参类型,数据类型会被提升,char会提升为int
如果传入的数据类型大于声明的形参类型,需要显式类型转换
不能通过返回类型来区分重载方法
默认构造器
如果类中无构造器,编译器会自动创建一个默认构造器
如果已经声明了一个构造器,编译器不会创建默认构造器
this关键字
this相当于该对象的一个引用
this只能在方法内部使用
构造器中可以调用另一个构造器,用this加参数列表表示,但只能调用一个,且该调用语句必须置于最起始处
static
静态方法内不能调用非静态方法,反之则可以
可以用类本身调用
JAVA禁止全局方法(万物皆对象)
清理
注意的三点
1. 对象不一定会被垃圾回收
2. 垃圾回收不等于析构
3. 垃圾回收只与内存有关
一旦垃圾回收器准备释放一个对象,会先调用其finalize方法,再洗一次垃圾回收发生时才真正回收
finalize的用途
finalize只针对通过创建对象的方式以外的方式为对象分配的存储空间,即C和C++的情况
这种情况通常发生在使用“本地方法”(native method)的情况
如果JAVA虚拟机(JVM)没有发生内存耗尽的情况,就不会执行垃圾回收
使用finalize的情形
在对象被回收前发现存在的隐晦缺陷,比如打开的文件
垃圾回收器
垃圾回收器能提高对象的创建速度
垃圾回收器除了回收空间,还将存活的对象内存紧密排列
引用计数
简单,但速度慢
当对象间存在循环引用时,可能会出现引用计数不为零的情况
引用计数未被应用在任何JAVA虚拟机中
解决方法:从堆栈和静态存储区中的引用开始遍历,找到所有被指向的对象,以及对象包含的引用,反复进行直到全部被访问为止
停止-复制
先暂停程序,将存活的对象复制到另一个堆中,并且紧凑排放
缺点:
1. 需要多一倍空间
2. 在程序稳定时,只会产生少量垃圾,那么全部复制就很浪费
标记-清扫
通过引用遍历所有对象,给对象设置一个标记,标记完后开始清扫,只回收没有标记的对象
剩下的堆空间将是不连续的
generation
内存分配以内存块为单位,“停止-复制”的堆复制变成块复制
每个块用代数记录是否还存活,被引用则代数增加
垃圾回收器对上次新分配的块进行整理,因为大型对象占据整个块不会被复制,因此对处理大量临时对象很有帮助
成员初始化
JAVA保证所有变量在使用前都会被适当地初始化。对于没有初始化的局部变量,会产生编译错误
可以定义类成员变量时赋值
成员初始化顺序取决于定义顺序
构造器初始化
自动初始化无论如何都会发生,然后才调用构造器
初始化顺序
变量定义的顺序决定了初始化的顺序
静态数据初始化
静态数据只占用一份内存,与对象个数无关
静态初始化只有在必要时才会进行。静态数据不会再被初始化
静态初始化在非静态初始化之前
对于一个Dog类,其产生对象的过程:
1. 构造器实际上是静态方法。由于构造器第一次被访问,JAVA解释器定位Dog.class
2. 载入Dog.class,这将会创建一个Class对象。静态初始化动作全部执行
3. 为对象分配内存空间
4. 该内存空间全部置零(默认初始化)
5. 执行字段定义处的初始化
6. 执行构造器
显示的静态初始化
多个静态初始化动作可以用一个static块包括
非静态实例初始化
该子句在构造器之前执行
可以用于保证无论哪个构造器被调用,某些操作都会发生
数组初始化
方括号可以放在标识符的前面或后面
所有数组都有一个成员length,会在越界访问时抛出异常
数组的创建是运行时的
初始化列表最后的逗号是可选的
可变参数列表
如果没有定义toString方法,在打印对象时会输出类名+”@”+地址
可变参数获得的依然是一个数组
传递0个参数是可行的
可以和自动包装机制搭配使用
枚举类型
创建enum时,会自动创建toString方法和ordinal方法
enum是类,具有自己的方法