Java中的四种引用类型是哪些
Java中的四种引用类型是哪些?
从一开始学习Java我们就知道Java的数据类型一般有两种,一种是基本数据类型,另一种是引用数据类型。其中,基本数据类型的值通常储存在栈内存中,用于对该类型的对象进行存储;而引用数据类型则在存储堆中对需要引用的对象进行引用。
引用是Java面向对象的一个特点,如果一个对象不曾被任何变量应用的话,那么整个程序也就无法再使用这一对象。四种引用类型可以说是在学习Java的过程中经常会接触到的。Java中主要包括了四种引用类型,分别是:强引用,软引用,弱引用以及虚引用。
一、强引用
强引用是一种最常见的引用形式,同时也较为普遍。是指创建一个对象并把这个对象直接赋给一个变量:
Student s = new Student();
String name = "周二鸭";
如果内存空间不足,Java虚拟机将会直接抛出
OutOfMemoryError
错误,从而程序将异常停止。强引用的对象是不会被 GC 回收线程回收的,不可以随意回收具有强引用的对象来解决内存不足的问题。在Java中,强引用是一种默认的状态,除非JVM虚拟机停止工作。
如果想终止一个强引用与一个对象直接的联系,可以将对象赋值为null,那么JVM就可以在合适时间将这个对象回收。
Student s = new Student();
s = null;
二、软引用
软引用和强引用不同,如果内存空间足够多,一个对象被软引用,则垃圾回收器不会将其回收;如果内存空间不足,这些引用对象就会被回收。所以,软引用就是当回收器没有回收某个对象时,程序就可以对其使用。它可用来较为敏感的高速缓存,虚拟机可以将软引用加入到与之向关联的队列。下面利用代码说明一下:
Student s = new Student();
SoftReference<Student> softRef = new SoftReference<Studnet>(s);
此时,对于这个Student对象,有两条引用路径,一个是来自
SoftReference
对象的软引用,另外一个是来自于s这个变量的强引用。现在这个Student对象是不会被垃圾回收线程回收,接下来我们可以结束s对这个Student实例的强引用,将其置为null:
s = null
,那么此时如果内存空间足够的话,它就不会被回收:
s = (Student)softRef.get();
System.out.println(s);
如果内存空间不足,那么Student的实例对象就会被回收,上面代码就会获得null。
三:弱引用
弱引用的特点就是引用对象的生命周期较短。GC回收器在扫描内存区域是若发现弱引用,无论内存空间足够与否,弱引用对象都会被回收。但弱引用对象也可以加入队列,这样就可以不被回收。
Public class WeakRefDemo {
public static void main (String[] args) {
WeakReference<Student> ref = new WeakReference<Student>(new Student("周二鸭", 20));
System.out.println(ref.get());
// 通知 GC 线程回收资源
System.gc();
System.out.println(ref.get());
}
}
class Student{
public String name;
public int age;
public Student(String name,int age) {
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "hello";
}
}
上面代码输出:
hello \n null
;
弱引用 与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
如果这个对象是偶尔的使用,并且希望在使用时随时就能获取到,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象。
四:虚引用
虚引用
也称为幻影引用:一个对象是都有虚引用的存在都不会对生存时间都构成影响,也无法通过虚引用来获取对一个对象的真实引用。唯一的用处:能在对象被 GC 时收到系统通知,JAVA 中用
PhantomReference
来实现虚引用。