关于Java的四大引用

简介: Java 引用

java的引用类型共四种

1:强引用

2:软引用

3:弱引用

4:虚引用

什么是强引用?

在java中普遍情况下我们会直接new Object(); 这种写法来创建一个对象 这种写法通常就是所谓的强引用,强引用的特别之处在于 假设当前程序即将OOM 那么在OOM来临 JVM会保证进行一次GC 当GC遇到强引用的对象 宁愿OOM也不会去回收该对象。当然 我们可以手动对该对象置空 或者 超出作用域时 GC就会对这类对象进行回收。

//code
public static void main(String[] args) {
    Object o = new Object();//一个强引用对象
    o=null;//同样 gc来了 会回收
}
public static void test(){
    //超出了作用域的对象 会被gc来临时 
    Object o = new Object();
}
复制代码

什么是软引用?

在Java中 用SoftReference 关键字包裹的对象就是一个软引用比如

SoftReference<byte[]> softReference = new SoftReference(new byte[1024]);///这是一个软引用对象
复制代码

软引用对象的特点是 在JVM即将OOM前 JVM会保证进行一次GC 那么当GC遇到当前对象只剩软引用的话 就会对它进行回收 通俗的说 一个对象只能软引用引用的话 就会在内存不足的情况下被回收

SoftReference<byte[]> softReference = new SoftReference(new byte[1024]);
System.out.println(softReference.get().length);
///假设我们再创建bytes对象时 内存不足了 这个时候 JVM会让GC干活 GC扫描到软引用对象 就会回收
byte[] bytes = new byte[1024];
System.out.println(softReference.get());//这个时候 再次 get  就会为空
复制代码

为了更好理解只剩一个对象引用

byte[] b = new byte[1024];
SoftReference<byte[]> softReference = new SoftReference(b);
System.out.println(softReference.get().length);
///假设我们再创建bytes对象时 这个时候 由于b对象不是只有一个引用 它有一个强引用 和一个软引用 我们的内存不足以创建 bytes时 就会触发OOM
byte[] bytes = new byte[1024];
复制代码

什么是弱引用?

弱引用是一个比软引用还是"软"的引用  软引用可以看成是 弱引用的plus版本。 弱引用的特点是:当对象只剩一个弱引用对象时 任何时候 GC只要一遇到弱引用对象 就会对它进行回收。

WeakReference<byte[]> weakReference = new WeakReference(new byte[1024]);
System.out.println(weakReference.get().length);
System.gc();
System.out.println(weakReference.get());/// null 因为被gc了
复制代码

什么是虚引用?

虚引用是四大引用中最弱的一种 它有一个特点 就是 无法通过get方法获取引用的对象

public class PhantomReference<T> extends Reference<T> {
    public T get() {
        return null;///get 方法 永远返回的是null。所以我们无法获取对象
    }
    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }
}
复制代码

而且虚引用在创建时 必须需要传入一个ReferenceQueue(引用队列) 而这个引用队列 会在对象销毁时 添加到这个队列里。

java中就时用虚引用管里堆外内存的 。( 知识点来自:马士兵java)

引用的特例

在之前测试时 为发现一个非常基础的知识被我遗忘了

WeakReference<Integer> wr1 = new WeakReference(new Integer(123));
WeakReference<Integer> wr2 = new WeakReference(123);
System.gc();
System.out.println(wr1.get());//会打印出null
System.out.println(wr2.get());//会打印出123
复制代码

如果你不知道为什么 可能需要继续往下看

其实很简单 在Java中 有缓存池的概念。一些常用的基础类型 会存储在这些缓存池中 比如说下面类型:

String str = "123";//java会在字符串缓存池 寻找相同的 如果没有就创建 有的直接引用
int i = 123;// int 会缓存 -128 到 127 间的所有数字  
byte;//会缓存所有的byte
boolean; //同样会缓存所有的值 当然 也只有false true


作者:FeanCheng

链接:https://juejin.cn/post/6844904136090075150

来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

目录
相关文章
|
3月前
|
安全 Java
从零开始学习 Java:简单易懂的入门指南之不可变集合、方法引用(二十六)
从零开始学习 Java:简单易懂的入门指南之不可变集合、方法引用(二十六)
|
4天前
|
Java
Java基础之对象的引用
Java基础之对象的引用
5 0
|
1月前
|
存储 Java C语言
【Java】以数组为例简单理解引用类型变量
【Java】以数组为例简单理解引用类型变量
15 1
|
1月前
|
缓存 Java
Java四个引用
Java四个引用
|
1月前
|
Java
[java进阶]——方法引用改写Lambda表达式
[java进阶]——方法引用改写Lambda表达式
|
4月前
|
Java
java 父类引用指向子类对象
java 父类引用指向子类对象
25 0
|
4月前
|
Java
Java中引用的概念
Java中引用的概念
32 1
|
4月前
|
Java
【Java代码】使用双冒号 :: 简洁代码及方法引用(静态方法+构造方法+实例方法+函数式编程举例)
【Java代码】使用双冒号 :: 简洁代码及方法引用(静态方法+构造方法+实例方法+函数式编程举例)
28 0
|
4月前
|
存储 Java
Java之Stream流及方法引用的详细解析二
2.6Stream流综合练习【应用】 案例需求 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作 男演员只要名字为3个字的前三人 女演员只要姓林的,并且不要第一个
51 0
|
4月前
|
数据采集 Java API
Java 正则表达式【非贪婪匹配、格式验证、反向引用、API】
Java 正则表达式【非贪婪匹配、格式验证、反向引用、API】