Java的引用类型常用的四种方法

目录
  • 前言
  • 强引用FinalReference
  • 软引用SoftReference
  • 弱引用weakReference
  • 虚引用PhantomReference

前言

今天看代码看到有牵扯到弱引用的东西,就先稍微补一补Java的四种引用类型吧。Java为引用类型专门定义了一个类Reference,它是引用对象的抽象基类。

这个类定义了所有引用对象共有的操作。 由于这个类和垃圾收集器是息息相关的,这个类不能直接子类化。

Reference有4个子类,分别为强引用FinalReference、软引用SoftReference、弱引用weakReference、虚引用PhantomReference。

意思就是这四种引用是在JVM中GC用的,我们工作写代码根本用不着。

强引用FinalReference

Object obj = new Object();

上面我们new了一个Object对象,并将其赋值给obj,这个obj就是new Object()的强引用。
Java中的引用默认就是强引用。

强引用的特性是只要有强引用存在,被引用的对象就不会被垃圾回收。只有强引用不存在了,被引用的对象才会被垃圾回收。

写个demo吧,新建一个BeanA,重写finalize方法:

public class BeanA {
    @Override
    protected void finalize(){
        System.out.println("将对象从内存中清除出去");
    }
}

然后写个测试方法,将强引用置为空后,通知JVM垃圾回收。

    public static void main(String[] args) throws IOException {
        BeanA a = new BeanA();
        a=null;
        System.gc();
        //防止gc线程结束后还未执行finalize方法
        System.in.read();
    }

输出结果:将对象从内存中清除出去。

可以看到强引用不存在了,被引用的对象是可以被垃圾回收的。

软引用SoftReference

软引用是用于描述一些有用但非必需的引用。

SoftReference的实例保存一个Java对象的软引用,该软引用的存在不影响垃圾回收线程对该Java对象的回收。

意思就是只有在内存不足的情况下,被引用的对象才会被回收,内存够用是不会被回收的。

只要垃圾回收器没有回收它,该对象就可以被程序使用。和这个软引用是没有关系的(即没有将软引用置空),只和内存有关。

直接看demo:

public static void main(String[] args){
        SoftReference<byte[]> soft = new SoftReference<>(new byte[1024*1024*10]);
        System.out.println(soft.get());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.gc();
        //注释掉下面这句两次get()方法都能获取到
        //byte[] bytes = new byte[1024 * 1024 * 15];
        System.out.println(soft.get());
    }

我们创建了一个SoftReference对象,其变量名soft强引用着这个SoftReference对象,而这个SoftReference对象则保存着一个软引用,这个软引用引用的是一个10M的数组。

当然这个10M数组也可以替换成自己新建的对象:

A a=new A();
SoftReference<A> soft =new SoftReference<>(a);

这样的话SoftReference对象中保存的a就变成了软引用,如果内存足够的话,将a=null,GC后使用soft.get还是可以获取到该对象。

我们这里使用10M数组来测试,启动测试类设定VM内存20M,发现再新建一个15M数组后会将原来的10M数组给GC掉。

输出结果:

[B@2cfb4a64
[B@2cfb4a64

[B@2cfb4a64
null

总结一句话就是:创建强引用时内存不够就把软引用占的内存给回收掉。

总结一个词就是:欺软怕硬。

另外软引用非常适合缓存使用。

弱引用weakReference

弱引用和软引用很类似,不同的是弱引用引用的对象只要垃圾回收执行,就会被回收,而不管是否内存不足。

我demo没有设定vm:Xmx=20M,通知JVM进行垃圾回收后依然会将被引用对象回收掉。

    public static void main(String[] args){
       WeakReference<byte[]> soft = new WeakReference<>(new byte[1024*1024*10]);
        System.out.println(soft.get());
        //通知JVM进行垃圾回收
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(soft.get());
    }

输出结果:

[B@2cfb4a64
null

虚引用PhantomReference

首先,虚引用是无法通过get方法来获取的。一个虚引用对象被回收时会被放在一个ReferenceQueue队列中,意思就是虚引用回收时会给出一个信号放在队列中。

        ReferenceQueue<Object> rq = new ReferenceQueue<>();
        Object obj = new Object();
        PhantomReference<Object> phantomReference = new PhantomReference<>(obj,rq);
        obj = null;
        System.out.println("Reference: "+phantomReference.get());
        System.gc();
        Reference<Object> r = (Reference<Object>)rq.poll();
        System.out.println("ReferenceQueue:  "+r);

输出结果两个null。只有VM内存不足时才会回收这个虚引用,才会将其放在队列中,才能通过poll()获取到队列中的PhantomReference对象,而这个引用对象需要程序员自己进行特殊处理。

那问题来了,甭管G不GC我都拿不到它,那它有啥用?

其实它一般用来管理直接内存,我们的垃圾回收器是在JVM中管理内存的,如果我们从网络中下载一个文件保存在os的内存中,而 新版JVM不需要copy一份到jvm内存中,通过引用可以直接访问操作系统管理的内存,当我们回收这个虚引用时,则会在队列中放入这个引入对象,方便用来特殊处理。

到此这篇关于Java的引用类型常用的四种方法的文章就介绍到这了,更多相关Java引用类型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 简述Java中的四种引用类型

    简介 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用,下面分别介绍下这四种引用. 强引用 强引用是最常用的引用类型,如下所示,new Object()会创建一个Object对象并存储在堆上,变量object存储对该对象的强引用. Object object = new Object(); 强引用不会被垃圾回收,所以要想回收该对象,则应该将指向该对象的变量显示设为null,这样该对象就由强引用转变

  • Java中的引用类型和使用场景详细

    目录 1.强引用 2.软引用 3.弱引用 4.弱引用的使用场景 5.虚引用 Java中的引用类型有哪几种? Java中的引用类型分成 强引用 , 软引用 , 弱引用 , 虚引用 . 1.强引用 没有引用指向这个对象,垃圾回收会回收 package git.snippets.juc; import java.io.IOException; public class NormalRef { public static void main(String[] args) throws IOExcepti

  • Java中值类型和引用类型详解

    我们都知道java是一种面向对象的编程语言,但是在实际意义上java并不是纯面向对象,因为面向对象的意义就是万物皆对象,那么如果说int类型的变量也是一个对象的话,那么我们应该能用"."这个东西访问到它的属性或者是方法,例如: import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<Integer>

  • Java ArrayList中存放引用数据类型的方式

    目录 ArrayList中存放引用数据类型 看下面一个例子 Java 引用数据类型 ArrayList集合 引用数据类型(类) ArrayList 集合 ArrayList中存放引用数据类型 ArrayList中存放引用类型时,存放的是一个引用,因此在放入ArrayList之后再进行改动会影响到ArrayList中的值 看下面一个例子 import java.util.ArrayList; public class Student implements Cloneable{ private in

  • java 引用类型的数据传递的是内存地址实例

    目录 java 引用类型的数据传递的是内存地址 看下面的代码和截图 list集合存引用数据类型时的问题 集合list的存储元素 java 引用类型的数据传递的是内存地址 java中引用类型的数据,传递的是内存地址,像类,数组,接口,String等等都是引用类型! 看下面的代码和截图 public class Test2 { // java中引用类型的数据传递的是内存地址 private Map<String, Student> students = new Hashtable<Strin

  • 四种引用类型在JAVA Springboot中的使用详解

    目录 概念介绍 01.  强引用 02.  软引用 03.  弱引用 04.  虚引用 对象可达性 Springboot源码中的使用 总结 概念介绍 不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响. 01.  强引用 这个就是我们创建的普通对象了~ 当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回 02.  软引用 软引用( SoftReference ) , 当内存不足 时会被回收 比如

  • 详解Java的引用类型及使用场景

    每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过"引用".在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Reference).虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱,今天这篇文章就简单介绍一下这四种类型,并简单说一下他们的使用场景. 1. 强引用(Strong

  • 聊聊java中引用数据类型有哪些

    目录 java中引用数据类型有哪些 下面说说java中引用数据类型: 一.类Class引用 二.接口interface引用 三.数组引用 数组的定义 数组的初始化 初始化数组的两种方式: 为什么Java里有基本数据类型和引用数据类型? java中引用数据类型有哪些 Java中有俩种数据类型,其中主要有8中基本数据类型和引用数据类型,除了8中基本数据类型以外都是引用数据类型,8中基本数据类型分别是byte,short,int,long,char,boolean,float,double,具体如下:

  • java 引用传递的三种类型小结

    目录 java引用传递的三种类型 第一种 第二种传递方式 第三种传递方式 对于三种引用传递的理解 java引用传值问题 问题起源,一个蠢到家的是失败案例 两类参数传递 基本数据类型 引用数据类型 引用传递 反过来再解决这个案例 java引用传递的三种类型 我这里使用了mldn视频里的例子,只用于学习交流. 第一种 结果:调用前:50 调用后:1000 分析: 理解:好理解 第二种传递方式 先看例子 运行结果: 分析图片: 第三种传递方式 结果: 分析: 对于三种引用传递的理解 第一种和第三种都好

  • Java的引用类型常用的四种方法

    目录 前言 强引用FinalReference 软引用SoftReference 弱引用weakReference 虚引用PhantomReference 前言 今天看代码看到有牵扯到弱引用的东西,就先稍微补一补Java的四种引用类型吧.Java为引用类型专门定义了一个类Reference,它是引用对象的抽象基类. 这个类定义了所有引用对象共有的操作. 由于这个类和垃圾收集器是息息相关的,这个类不能直接子类化. Reference有4个子类,分别为强引用FinalReference.软引用Sof

  • java调用WebService服务的四种方法总结

    目录 一.前言 二.简介   三.具体解析 第一种方式,首先得下载axis2的jar包,Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码. 第二种RPC 方式,强烈推荐. 第三种:利用HttpURLConnection拼接和解析报文进行调用. 第四种,利用httpclient 总结 一.前言 本来不想写这个的,因为网上类似的是在是太多了.但是想想自己前面段时间用过,而且以后可能再也没机会用了.所以还是记录一下吧.我这儿是以C语言生成的W

  • java读取XML文件的四种方法总结(必看篇)

    JAVA操作XML文档主要有四种方式,分别是DOM.SAX.JDOM和DOM4J,DOM和SAX是官方提供的,而JDOM和DOM4J则是引用第三方库的,其中用的最多的是DOM4J方式.运行效率和内存使用方面最优的是SAX,但是由于SAX是基于事件的方式,所以SAX无法在编写XML的过程中对已编写内容进行修改,但对于不用进行频繁修改的需求,还是应该选择使用SAX. 下面基于这四种方式来读取XML文件. 第一,以DOM的方式实现. package xmls; import org.w3c.dom.D

  • java获取当前时间的四种方法代码实例

    这篇文章主要介绍了java获取当前时间的四种方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 第一种:Date类 public class DateDemo { public static void main(String[] args) { Date day = new Date(); SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); S

  • Java中ArrayList初始化的四种方法详解

    1 起因 在实际业务开发中, 我们经常会遇到需要临时创建一个数组的情况, 今天我们就来讲一下Java中ArrayList初始化的方法 2 解决方案 直接上结论, 总共有四种初始化方法: 双括号法 Arrays.asList stream Lists 2.1 双括号法 List<Integer> test = new ArrayList<Integer>(){{ add(1); add(2); }}; 2.2 Arrays.asList List<Integer> tes

  • Java复制文件常用的三种方法

    复制文件的三种方法: 1.Files.copy(path, new FileOutputStream(dest));. 2.利用字节流. 3.利用字符流. 代码实现如下: package com.tiger.io; import java.io.*; import java.nio.file.*; /** * 复制文件的三种方式 * @author tiger * @Date */ public class CopyFile { public static void main(String[]

  • PHP取整数函数常用的四种方法小结

    ceil - 进一法取整 说明 float ceil ( float value ) 返回不小于 value 的下一个整数,value 如果有小数部分则进一位.ceil() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大. 例子 1. ceil() 例子 复制代码 代码如下: <?php echo ceil(4.3); // 5 echo ceil(9.999); // 10 ?> floor - 舍去法取整 说明 float floor ( float

  • java arrayList遍历的四种方法及Java中ArrayList类的用法

    java arrayList遍历的四种方法及Java中ArrayList类的用法 package com.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayListDemo { public static void main(String args[]){ List<String> list = new ArrayList<String

  • java对象转化成String类型的四种方法小结

    目录 方法1:采用 Object#toString()方法 方法2:采用类型转换(String)object方法 方法3:采用 String.valueOf(Object) 方法 方法4:采用 ""+object方法 在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object#toString(),(String)要转换的对象,String.valueOf(Object)等. 方法1:采用 Object

  • java map遍历的四种方法总结

    整理了关于java中map的遍历的四种方法: import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;publicclassMapTest{privateMap<String,String> map;publicMapTest(){  map =newHashMap<String,String>();

随机推荐