转载

Thinking in Java:初始化与清理

版权声明:此文章转载自ITeye。

如需转载请联系听云College团队成员阮小乙,邮箱:ruanqy#tingyun.com

一 Java初始化 

Java通过使用构造器来初始化,构造器与类的名字相同,是一种特殊类型的方法,因为没有返回值。

二 方法重载 

Java允许方法名一致,区分方法:

1 参数个数,种类不同

2 参数顺序不同

为什么Java不允许以返回值区分?

Java代码

void f(){}   int f(){return 1;}

如果我们调用的时候:f();

Java如何判断调用哪个f()呢,so这种区分方法不行。

三 this关键字 

Java代码

public class Test1 {       public static void main(String[] args) {           Test1 a = new Test1();           Test1 b = new Test1();                      a.f(1);           b.f(1);          }              int f(int i){           return i;       }      }

Java是为了发送消息给对象,这时编译器做了一些操作把所操作对象的引用也传给了f(),实际上应该是

Test1.f(a,1);Test1.f(b,1);

假设你想在方法内部获得对该对象的引用,那么就使用this关键字。

直接调用同一个类的其他方法,无需使用this,编译器会自动处理。

四 static关键字 

static方法内部不能调用非静态方法,可以在没有创建对象的前提下通过类型调用,这也是static方法的主要用途。

五 垃圾回收器原理 

1 首先了解下一种简单的垃圾回收机制-->引用计数,它是一种简单但速度很慢的垃圾回收技术。每个对象都有一个引用计数器,当有引用连接对象时,引用数加1,当引用离开作用域或被置为null时,引用数减1。

虽然管理引用计数的开销不大,但这项开销在整个生命周期中都存在。

垃圾回收器遍历对象,引用数为0的,就释放其占用的空间。

如果对象之间存在循环引用,可能会出现“对象应该被回收,但计数不为0”,这种情况需要的工作量很大,Java编程思想作者 Bruce Eckel指出似乎这种方法从未在任何一种JVM上实现。

2 更好模式的指导思想:对任何存活的对象,一定能追溯到其存活在堆栈或静态存储区之间的引用。

Java虚拟机采取了一种自适应的垃圾回收技术,有一种作法:停止-复制。

暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部是垃圾,对象搬家后,指向它的引用必须修正。

程序进入稳定状态后,可能只产生少量垃圾,这种方法就很浪费,为了更高效,Java就会进行检查,要是没有新垃圾产生就切换到另外一种模式:标记-清扫。

3 标记-清扫思想:从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当找到一个存活的对象,就会给对象一个标记,这个过程不会回收任何对象。只有在全部标记工作完成后,清理动作才会开始,没有标记的对象被释放。

标记-清扫也要在程序暂停的情况下运行。

4 内存分配以较大的“块”为单位,如果对象较大,它会单独占用一块,大型对象不会被复制,每次停止-复制后其代数会增加,如果没用引用,那么直接释放。

5 如果程序运行时,所有对象都很稳定,那么JVM使用标记-清扫方式,要是堆空间出现很多碎片,那么就切换为 停止-复制

这就是自适应,你可以理解为自适应、分代的、标记-清扫、停止-复制式垃圾回收器。

深入解析垃圾回收机制: http://my.oschina.net/winHerson/blog/114391

六 成员初始化顺序 

Java代码

public class TestIntialize {          {           System.out.println("1");       }              static{           System.out.println("11");       }              TestIntialize(){           System.out.println("111");       }              public static void main(String[] args) {           new xxx();           System.out.println("----------------");           new xxx();       }   }   class xxx extends TestIntialize{       {           System.out.println("2");       }              static{           System.out.println("22");       }              xxx(){           super();           System.out.println("222");       }      }

执行结果:

11  22  1  111  2  222  ----------------  1  111  2  222

由这段实例,可以看出初始化顺序先执行静态块,类加载时,静态块便会加载,而且只加载一次,然后执行动态代码块,最后执行构造函数。

静态块-->动态块-->构造函数

想阅读更多技术文章,请访问听云技术博客,访问听云官方网站感受更多应用性能优化魔力。

原文  https://blog.tingyun.com/web/article/detail/398
正文到此结束
Loading...