返回首页
当前位置: 主页 > 网络编程 > Jsp实例教程 >

Java语言里的四种引用类型

时间:2015-05-15 20:55来源:知行网www.zhixing123.cn 编辑:麦田守望者

Java语言里的引用类似于C/C++语言里的指针,通过引用可以对堆中的对象进行操作。在Java语言中的引用机制里,有四种引用。

一、强引用
这是最常用最普遍的一种引用。一般而言,大多数情况下默认使用的引用就是强引用。比如当你在函数体中创建了一个对象,该对象被分配在堆中,那么通过对象的引用就可以对该对象进行操作。比如:

 


StringBuffer str = new StringBuffer("not a hello world");

如果上述语句在函数体内运行,那么str做为局部变量是分配在栈上,但StringBuffer类的实例对象”not a hello world”则是分配在堆上。此时str指向StringBuffer实例所在的堆空间,通过str变量就可以操作该实例了,这时str就是StringBuffer的引用。
当然,如果在上述语句之后代码里还有一个赋值语句,如:

 


StringBuffer str1 = str;

则str1也会在栈上分配有空间存储,也是StringBuffer实例的引用,此时该实例就有两个引用。如果这时执行“==”操作,判断的是两个引用,指向的实例所在的堆空间的地址是否相同,而不是两个实例是否相同。
上面提到的都是强引用。
一般来说,强引用可以直接访问目标对象。当对象实例还有强引用指向时,就不会被JVM回收。但这样也容易有OutOfMemoryException的隐患。

二、软引用
软引用是除了强引用以外最强的引用类型。其构造使用代码如下:

 


StringBuffer str = new StringBuffer("not a hello world");
SoftReference<StringBuffer> softRerference = new SoftReference<StringBuffer>(str);

这里的softRerference就是对对象实例的软引用。
软引用的特点在于只有其指向的对象实例不会很快的被JVM回收,其只会在堆内存使用很紧张接近阀值时才会回收掉。只要有足够大的内存空间,软引用是可以在内存里存活的。所以这种特点让其适用于对内存空间敏感的Cache。

三、弱引用
弱引用是比软引用还弱的引用类型,使用的构造代码与软引用类似,把SoftReference改成WeakReference即可。其特点是不管内存空间使用多少,只要JVM进行GC时,发现有弱引用都会对其进行回收。当然,垃圾回收的线程优先级也比较低,如果内存足够,那么弱引用的对象也可以存活很久。
弱引用的特点使其可以适用于可有可无的缓存场景。当内存充足时缓存的对象数据可以加速系统,内存紧张时又会被回收掉。

四、虚引用(又叫幽灵引用)
虚引用、幽灵引用,顾名思义,是虚无缥缈的一种引用,是最弱的一种引用。一个对象有虚引用时,相当于没有引用,其随时都可能会被回收掉,并且其返回值永远都是null。我们看JDK源码时就会看到PhantomReference里的get()方法实现如下:

 


public T get(){
return null;//任何情况下都是只返回null
}

那么虚引用的存在意义是什么呢?它必须是跟引用队列(ReferenceQueue)一起使用的,用来跟踪垃圾回收的过程。
其构造使用的代码如下:

 


Object ref = new Object();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(ref, new ReferenceQueue<Object>());

当ref被回收时,GC会让该引用进入到引用队列中,此时判断引用队列里有该对象时,我们即可做一些回收前的业务处理,比如记录日志一类的操作。
其实软引用和弱引用里也有类似用法,即构造时与一个引用队列同用,并且在被回收时GC也会将其放入队列中,那么虚引用与其的区别是什么呢? 我们知道Object 的 finalize方法是在gc执行前被调用的,如果某个对象重载了finalize方法,在其内创建本身的强引用(不管是有意的还是无意的)都将导致这一轮的GC无法回收这个对象。并有可能引起很多次GC,最后会导致JVM内有很多Garbage却OutOfMemory,使用PhantomReference就可以避免这个问题,因为PhantomReference是在finalize方法执行后回收的,也就意味着此时已经不可能拿到原来的引用,也就不会出现上述问题。

一般的应用编程不会涉及到Reference编程,但是了解这些知识会对理解GC的工作原理以及性能调优有帮助,在实现一些基础性设施比如缓存时也可能会用到。

------分隔线----------------------------
标签(Tag):Java JAVA实例教程 JAVA基础教程 Java源代码 Java技巧
------分隔线----------------------------
推荐内容
猜你感兴趣