文章标题
2016-11-22 14:49
197 查看
《Thinking in Java》中文
第五章 初始化与清理
5.3: 如果定义了一个构造器,编译器将不会自动创建默认构造器5.4.2: 关于static,不存在this。因为不存在对象
关于finalize()方法: System.gc() 通知回收垃圾.
1.对象可能不被垃圾回收
2.垃圾回收不等于C++里面的析构
3.垃圾回收只与内存有关
注意:垃圾回收只有在濒临存储空间将要用完的时候才会调用,毕竟垃圾回收也会有大量开销。 实际上这里面会调用本地方法如C/C++的free();
垃圾回收期的工作方式:
“自适应的,分代的,停止-复制,标记-清扫”
停止-复制: 暂停程序的运行,复制活的对象到另一个堆。这样他们将会整齐排列,堆指针就可以快速移动到附近未分配的空间上开辟新的空间,提高了堆分配空间的速度。 但是很浪费空间
标记-清扫: 遍历所有引用,给存活对象标记,全部遍历完成后再清扫。但是剩余的空间不再是连续的了。速度很慢,但是当程序进入稳定期,不产生或者少量产生垃圾时候就很快了。
虚拟机会检测当前的堆空间碎片,来切换方式。
其余的提速技术:JIT(Just-In-Time 即使编译器技术)。把程序部分或全部翻译成本地机器码,把.class装载时,惰性评估,只在必要的时候才编译代码,不被执行的代码不会被编译。通常来讲,代码执行次数越多,速度就越快.
关于初始化:
局部变量编译时错误的方式确保必须初始化.(局部变量不能出现private等等权限修饰)
function(){ int i ; i++; //报错 }
但是在对象中,类的字段会有默认值。就能被使用。
构造器的初始化顺序:
请看代码:
class Window{ Window(int mark){ System.out.println("Window: " + mark); } } class House{ Window w1 = new Window(1); House(){ System.out.println("House"); w3 = new Window(33); } Window w2 = new Window(2); void f(){ System.out.println("f"); } Window w3 = new Window(3); } class InitTest{ public static void main(String[] args) { House h = new House(); h.f(); } }
注意:变量定义的先后顺序决定初始化顺序。都会在构造器调用前被调用。所以这里输出是:
Window: 1
Window: 2
Window: 3
House
Window: 33
f
Java的初始化顺序:
父类静态代码块
子类静态代码块
父类代码块
父类构造函数
子类代码块
子类构造器
注意:static是在装载类的时候,实例化的是非静态
同时 成员变量和代码块的优先级是相同的,取决于出现顺序