`
rijin
  • 浏览: 139449 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java语言里的四种引用类型

    博客分类:
  • Java
阅读更多
原文同时还记录在笔者博客:http://www.newhottopic.com/2013/04/05/java-reference/


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的工作原理以及性能调优有帮助,在实现一些基础性设施比如缓存时也可能会用到。
1
5
分享到:
评论

相关推荐

    Java语言规范

    , 基于最新Java SE 8,完整且准确地阐述Java编程语言及其规范,是深度了解Java语言及其技术细节的权威参考书。, 本书由Java技术的发明者编写,是Java编程语言的权威性技术指南。如果你想知道Java语言构造的精确含义...

    Java语言程序设计

    目录第1章 Java语言基础知识 1.1 Java语言与面向对象的程序设计 1.1.1 面向对象的程序设计思想 1.1.2 Java语言的特点 1.1.3 Java类库 1.2 Java程序概述 1.2.1 Java开发环境 1.2.2 Application举例 1.2.3 ...

    Java语言的方法参数浅析

    通过对典型程序的研究与分析可以看出JAVA语言的参数传递总是传值调用的,但是对于基本类型的参数和对象类型的参数来说,参数传递的情况不完全相同.Java语言不能直接使用传引用调用,但是可以通过数组的方式模拟传引用...

    java手册中英文java8,java9手册

    太阳微系统对Java语言的解释是:“Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言” Java不同于一般的编译语言或解释型语言。它首先将源代码编译成...

    JAVA基础——JAVA的五种引用类型及引用队列

    JAVA 的五种引用类型及引用队列 ​ 在介绍 JAVA 的五种引用之前,先介绍一下什么是引用,以及引用和对象之间的关系 什么是引用 ​ 众所周知,JAVA 是一种面向对象的语言,在 JAVA 程序运行时,对象是存储在堆内存...

    java教程课件5基本数据类型与引用类型

    java.applet:包含一些用于创建Java小应用程序的类。...java.lang:包含一些Java语言的基本类与核心类,如String、Math、Integer、System和Runtime,提供常用的功能,这个包中的所有类是被隐式导入的。

    Java是一种广泛使用的编程语言

    Java是一种静态类型的、类基础的、并发性的、面向对象的编程语言。以下是一些Java的主要特性: 平台独立性:这是Java最著名的特性。Java采用"一次编写,到处运行"的方法。Java程序在任何支持Java的平台上都可以运行...

    Java语言的科学与艺术(国外计算机科学经典教材)

    但Java语言很复杂,老师和学生们在理解Java语言的结构时,复杂性成为了最大的障碍。  在本书中,斯坦福大学教授、著名的计算机科学教育领导者Eric S.Roberts着重强调了更适合于初学者的友好讲解方式,使用ACM Java...

    java的传值与传引用详解

    引用也是一种数据类型,我们可以把它想象为类似 C 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。  如果我们定义了不止一个引用指向同一个对象,那么这些引用是不...

    Java语言基础下载

    引用(Reference)类型 52 存储器分配和布局 53 this引用 55 Java编码约定 56 运算符的优先级 58 升级和表达式的类型转换 62 独立实践 70 第五章:数组 71 学习目标 71 数组的描述 72 创建数组 72 多维数组 78 拷贝...

    Java虚拟机规范.Java SE 8版.zip

    第2章概述Java虚拟机的整体架构,包括class文件格式、数据类型、原始类型、引用类型、运行时数据区、栈帧、浮点算法、异常等,这对理解本书后面的内容有重要帮助;第3章详述如何将Java语言编写的程序转换为Java...

    Java面试八股文解析.pptx.pptx

    Java语言特性 Java是一种面向对象的编程语言,具有跨平台、安全性高、易于维护等特点,广泛应用于企业级应用开发。 Java数据类型 Java拥有8种基本数据类型,包括整型、浮点型、字符型等,以及引用数据类型如数组和类...

    《Java程序设计案例教程》教学课件02Java语言基础.pptx

    模块2 Java语言基础 《Java程序设计案例教程》教学课件02Java语言基础全文共48页,当前为第1页。 学习目标 01 掌握标识符、关键字、分隔符、变量和常量的含义和使用方法。 02 了解Java注释的格式和代码书写风格。 03...

    Java 语言基础知识教程 PPT演示文稿

    1.1 Java语言与面向对象的程序设计 1.2 Java程序概述 1.3 基本数据类型与表达式 1.4 数组的概念 1.5 数组的创建和引用 1.6 本章小结

    第4章-Java面向对象程序设计-Java语言GUI程序设计-赵满来-清华大学出版社.pptx

    引用类型参数,相对应的实参和形参链接到同一个对象,在方法中改变了形参引用对象时,其实就是改变了实参引用的对象。 例4.2 TwoInt类中有两个int类型的属性,编写方法swap交换该类对象的两个属性的值,并显示交换...

    java技术学习文档.docx

    Java是一种面向对象的编程语言,它支持封装、继承和多态等面向对象的基本概念。Java具有静态类型检查机制,需要在编译时指定变量的类型。Java提供了基本数据类型,如int、double、float等,也支持引用数据类型,如类...

    jls-api-finder:查找 Java 语言规范中引用的所有 Java 平台 API 类型

    Java 语言与平台 ... 规范引用的一组直接和间接类型可以被视为平台 API 的“核心”部分,与 Java 语言本身密不可分。 去做 允许将规范中定义的类型名称列表作为输入提供 屏幕抓取 HTML 规范以定位直接引用的类

    Java基础知识之数据类型和操作符

    Java是一种强类型语言,这意味着在Java中,每个变量都必须先声明其数据类型,然后才能使用。Java的数据类型可以分为两类:基本数据类型和引用数据类型。基本数据类型包括byte、short、int、long、float、double和...

Global site tag (gtag.js) - Google Analytics