Java技巧------Reference引用

描述

首先什么是引用?什么是对象?这是一个基础的问题。我们看看一些简单的代码。

1
2
Object a;
a = new Object();

这里的a是一个引用,Object a只是声明了一个Object的引用,在第二行执行前,a是一个没有指向的引用。第二行中的new Object()建立了对象存到了堆中,由a = new Object()赋给了a这个引用。

1
2
3
4
Object a;
Object b;
a = new Object();
b=a;

同一个对象可以有多个引用。

1
2
3
4
Object a;
a = new Object();
a = new Object();
a = new Object();

一个引用可以指向多个对象。

引用分类

强引用

我们平时使用的最简单的就是强引用,比如

1
String s= "a";

强引用在java的垃圾回收机制中不会被回收,即使内存不够也不会回收,只会抛出OutOfMemoryError异常并终止程序。

软引用

软引用通过SoftReference类实现。

1
2
Object a = new Object();
SoftReference sa = new SoftReference(a);

这里的Object有两个引用,一个是a,是对其对象的强引用,一个是sa是对其的软引用,也可以这样单独建立一个软引用。

1
SoftReference<Object> sa = new SoftReference(new Object());

不同于强引用,在java的垃圾回收机制中如果出现内存不足的情况,这些软引用的对象会直接被回收。正因为这一特点,往往可以用来实现缓存。

弱引用

软引用通过WeakReference类实现。

1
2
Object a = new Object();
WeakReferencesa = new WeakReference(a);

同样这里的Object有两个引用,一个是a,是对其对象的强引用,一个是sa是对其的弱引用,也可以这样单独建立一个弱引用。

1
WeakReferencesa<Object> sa = new WeakReferencesa(new Object());

对于弱引用在垃圾回收机制中是这样运作的,如果没有其他的强引用或是软引用而只是一个弱引用的话,那么会直接被回收。但是我们不确定回收机制运行的具体时间,所以我们无法确定具体的回收时间。

虚引用

虚引用与其他三种都不同,它可以说是没有引用,使用与不使用并不会改变相关对象的生命周期。

1
2
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
PhantomReference<Object> sa = new PhantomReference(new Object(),queue);

使用虚引用必须要和ReferenceQueue一起使用,当回收机制在回收时发现相关的对象还保留有虚引用时,会将其加入与之关联的ReferenceQueue中,我们可以通过对ReferenceQueue的操作来查看其是否被回收,所以一般使用虚引用来追踪回收过程。

小结

根据不同的需求,我们可以设置不同的引用类型进行内存管理,优化我们的程序,源码分析详见Java源码阅读——Reference