对象引用及对象赋值
一、对象引用与对象创建
Object obj = new Object();
- Object:类对象,存放在方法区中
- Object obj:类引用变量,即类的实例对象的引用,存放在Java虚拟机栈中的局部变量表
- new Object:形成了一块存储了Object类型所有实例数据值(对象中各实例字段的值数据)的结构化内存,存放在堆区
- ():类对象中构造方法,対生成的对象进行初始化;类对象中一定有构造方法,系统默认提供无参的构造方法,如果现实声明其他构造方法,则系统不提供默认的构造方法
- =:操作符使对象引用指向刚创建的那个Object对象,即 obj 中存放 new Object() 在堆中的空间的首地址
Object obj = null ; // ojb 对象引用指向 null
obj = new Object(); // obj 对象引用指向 新对象
Object obj1 = obj ; // 此时 obj obj1 指向都一个对象
对象引用与对象的关系
- 一个对象引用可以指向0个或1个对象(即对象引用可以指向null)
- 一个对象可以有N个引用指向它(即对象引用存放的同一个对象在堆中的空间的首地址)
- 通过一个对象的引用来对对象进行操作
// obj 原来指向 new Object();若此时 obj1 = null ;
// 那么当 obj 指向新对象后,原来的无引用指向的 new Object()
// 将会成为垃圾回收机制的处理对象,何时回收由GC控制
obj = new ObjectOther(); // 再次为 obj 赋值,指向其他对象
System.out.print("abc") ; // 匿名字符串对象
System.out.print(new A().getA()); // 直接使用匿名对象中的方法
- 临时对象:对象与引用的关系将持续到对象回收。如:匿名对象
二、reference类型对象的引用有两种方式
1.句柄池
堆中将划出一块内存作为句柄池,reference中存储的是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息
2.直接引用
reference中直接存储的就是对象地址,对象地址存有指向方法区中类型数据的地址信息
3.
句柄的最大好处就是GC时,对象被移动时只需要改变句柄的实例数据指针;而reference不用修改
直接指针访问方式则速度快,节省了一次指针定位的时间,因对象访问在Java中非常频繁,故很有利,虚拟机Sun Hot Spot 就采用此方式
三、方法传参
参数为值传递,而不是引用传递;
对于基本数据类型,传递的是数据本身的值;
对应引用数据类型,传递的是对象的引用,即存放在堆中的地址值;
package com.java.study.test.unit8;
public class ParameterMethodMain {
private Integer i ;
private Integer j ;
private ParameterMethodMain(){
super();
}
private ParameterMethodMain(Integer i ,Integer j){
this.i = i ;
this.j = j ;
}
/**
* @param args
*/
public static void main(String[] args) {
// 1.基本数据类型,方法中传递的是值本身
// 方法中对值的修改不影响原来值的大小;
// 重新赋值:即改变原来的变量的内容,才会改变原来值的大小
// int 对应包装类 Integer ,Integer 为 final 修饰,同 String ,不可改变
int a = 0 ;
changeMethodBasic(a);
System.out.println(a); // 0
a = changeMethodBasic(a);
System.out.println(a); // 100
// 2.引用数据类型
ParameterMethodMain main = new ParameterMethodMain();
main.setI(1);
main.setJ(2);
// 传递的是对象数据类型的引用,指向同一个堆中的对象,
// Main()方法中的 main对象引用与方法中的main引用指向了同一个对象
// 所以对象的改变是共享的
changeMethodRefence(main);
System.out.println("i="+main.getI()+" j="+main.getJ());// i=3 j=4
// changeMethodRefenceNew 中的参数 ParameterMethodMain main
// 只是接收了Main()中main对象引用传递的对象的地址,而与main对象无关系
// 在changeMethodRefenceNew 中对形参main进行重新赋值,与Main()方法中的main对象无关
// 此处仅仅是命名相同而已
changeMethodRefenceNew(main);
System.out.println("i="+main.getI()+" j="+main.getJ());// i=3 j=4
// 改变了当前对象指向的内容,指向了新的对象
// 强制改变了Main()方法中main对象的引用中存放的地址
main = changeMethodRefenceNew(main);
System.out.println("i="+main.getI()+" j="+main.getJ());// i=5 j=6
// 3.String 是引用数据类型,但很特殊,因为String 的特点是对象不可变;
// 任何对已有的string对象的引用的操作都会产生新的对象
String str = new String("abc") ;
// changeStr 方法中的形参 String str 接收Main()方法中str的对象引用地址的传递
// changeStr 中对str重新赋值,实际是新生成了一个对象bcd,并将str指向了bcd对象
// 但changeStr 中仅仅是方法内部生效
changeStr(str);
System.out.println(str);
// 相当于Main()的 str 重新赋值,指向新的对象的地址
str = changeStr(str);
System.out.println(str);
}
public static int changeMethodBasic(int a){
System.out.println("a="+a); // a=0
a = 100 ;
System.out.println("a="+a); // a=100
return a ;
}
public static void changeMethodRefence(ParameterMethodMain main){
main.setI(3);
main.setJ(4);
}
public static ParameterMethodMain changeMethodRefenceNew(ParameterMethodMain main){
ParameterMethodMain newMain = new ParameterMethodMain();
newMain.setI(5);
newMain.setJ(6);
main = newMain;
return main;
}
public static String changeStr(String a){
a = "bcd";
return a ;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public Integer getJ() {
return j;
}
public void setJ(Integer j) {
this.j = j;
}
}
- 方法中传递参数,值传递而非引用传递
- 对于引用数据类型,方法中的形参是对调用位置传入的引用地址的拷贝,相当于同时又多了一个指向此对象的对象引用,所以方法中的形参修改对象时,影响调用此方法中的对象;但交换地方、重新指向新对象都不会影响调用方法中的对象,即相当于方法中的对象引用断开了与此对象间的绑定关系,但与调用方法中的对象引用无关
- 对于String,是引用数据类型,但String本身的特点是对象不可变,方法中的形参接收到传递的引用地址,对对象的修改都会产生新的String对象,也就是形参中的对象引用指向了新的对象
- 对于基本数据类型,传递的值
四、引用
索引强度:强引用 > 软引用 > 弱引用 > 虚引用,与GC有关
对比 | 强引用 | 软引用 | 弱引用 | 虚引用 |
英文 | Strong Reference | SoftReference | WeakHashMap | PhantomRefrence |
GC | 尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收 | 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用 | 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收;在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存 | 建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null;在任何时候都可能被垃圾回收器回收 |
作用 | - | 使用软引用构建敏感数据的缓存 | - | 虚引用主要用来跟踪对象被垃圾回收器回收的活动;当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中,程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动 |
ReferenceQueue | - | - | 可选 | 必须配合使用 |
定义 | 就是指在程序代码中普遍存在的,类似Object obj = new Object()这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象 | 是用来描述一些还有用但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常 | 用来描述非必须的对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发送之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。一旦一个弱引用对象被垃圾回收器回收,便会加入到一个注册引用队列中。 | 虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个持有虚引用的对象,和没有引用几乎是一样的,随时都有可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程 |
五、对象可达性的判断
- 对象引用关系:按照对象被谁引用,被一个或多个对象引用,组成已根级为顶点的树状结构;而不是以当前对象引用了哪个对象去统计
- 单条引用路径可达性判断:在这条路径中,最弱的一个引用决定对象的可达性。
- 多条引用路径可达性判断:几条路径中,最强的一条的引用决定对象的可达性。
举例:
箭头的方向代表了引用的方向,所指向的对象是被引用对象
A-->B-->C-->D
A-->E-->F-->D
B-->C强引用,C-->D弱引用,B-->C-->D弱引用
E-->F强引用,F-->D软引用,E-->F-->D软引用
D对象是软引用
博文参考:
Java引用类型
深入理解StrongReference,SoftReference, WeakReference和PhantomReference
对象访问分析
浅谈java对象引用及对象赋值
分享到:
相关推荐
面向对象的系统分析与设计是计算机科学领域中的一个重要主题,它涵盖了软件开发过程中的一些关键概念和技术。本资源包括了相关的课件和课后答案,帮助学习者深入理解这一主题。以下将详细介绍其中涉及的主要知识点:...
1. **对象唯一性**:每个对象都有一个独一无二的标识,确保在整个生命周期内可以唯一地识别和访问。 2. **分类性**:分类性允许我们通过抽象将具有相同属性和行为的对象归类为一类,简化了模型的复杂性。 3. **...
5. **封装**:封装是隐藏对象的属性和实现细节,只对外提供公共访问方式。它保护了数据的安全性,减少了错误发生的可能性,同时提高了代码的模块化。 6. **设计模式**:在面向对象设计中,设计模式是一种解决常见...
面向对象设计方法是一种重要的软件开发技术,主要用于将复杂的系统分解为一系列相互协作的对象。在UML(统一建模语言)中,这种设计方法被广泛应用于分析和程序设计之间,作为两者之间的桥梁。本章主要讨论了面向...
1. **封装**:封装是指将数据(属性)和操作这些数据的方法(行为)组合在一个独立的对象中,并对外部隐藏其内部细节,只提供外部可以访问的接口。 2. **继承**:继承允许创建一个类(子类)继承另一个类(父类)的...
面向对象分析与设计(第3版):深入解析与应用 《面向对象分析与设计(第3版)》是一本专注于面向对象编程方法论的重要教材,尤其针对Java开发者提供了详尽的指导。本书通过深入浅出的方式,不仅阐述了面向对象的...
面向对象分析与设计是软件开发过程中至关重要的环节,它涵盖了从需求理解到系统构建的一系列步骤,以提高软件的质量和可维护性。本知识体系主要围绕五个核心主题展开:方法、重构、模式、概念和原则。 首先,让我们...
它通过访问控制(如public、private和protected)来保护对象的内部状态,防止外部代码随意修改。 3. **多态性**:多态性是指同一种行为可以有不同的表现形式,具体取决于对象的类型。它允许我们使用一个接口来调用...
面向对象分析与设计是软件开发过程中的核心环节,它涵盖了如何使用面向对象的思维方式来理解和表述问题领域,以及如何设计出高效、可维护的软件系统。在这个领域,我们主要涉及三个关键概念:对象、类和继承,以及...
继承和泛化是实现代码重用和层次化设计的机制,而封装则通过信息隐蔽技术限制了对象内部状态的访问。面向对象分析的过程中,注重寻找对象、确定对象的属性和方法、组织类的设计,并通过动态模型和交互次序的图形化...
软件工程实验七-面向对象的分析与设计建模 本实验主要目的是掌握面向对象开发思想及实现机制,理解并掌握 UML 常用动态建模图,并掌握并运用 StarUML 建模工具。实验中,我们将使用 StarUML 或 Rational Rose 2016 ...
协作图则关注对象间的交互关系,强调它们如何协同工作,如修改用户信息时,用户、数据库访问层和存储数据库之间的交互。 4. **状态图建模**: 状态图描绘了对象在其生命周期内可能经历的不同状态及其转换。用户...
面向对象分析与设计(Object-Oriented Analysis and Design,简称OOAD)是软件工程领域中的一种重要技术,它主要用于构建复杂、可维护的软件系统。本课件是北大青鸟内部培训材料,全面且深入地讲解了面向对象的理论...
### 面向对象分析设计参考案例:网上书店系统WebLab #### 一、面向对象的概念及重要性 面向对象编程(Object-Oriented Programming,简称OOP)是一种软件开发方法,它通过“对象”这一基本单位来组织代码。对象是...
面向对象分析与设计是软件工程领域中一个至关重要的部分,特别是在高等教育阶段,如北京航空航天大学软件学院的教学中,这一主题占据了核心地位。谭火彬老师的课程致力于培养学生的面向对象思维和设计能力,以便他们...
根据提供的文件信息,有关《面向对象分析与设计 Grady 著 中文版(第三版)》的知识点将围绕面向对象分析与设计(Object-Oriented Analysis and Design, 简称OOAD)的主要概念进行详细说明。由于提供的部分内容重复...
### JavaScript面向对象之访问对象属性的两种方式分析 #### 一、引言 在JavaScript中,面向对象编程是一种常见的编程范式,它可以帮助开发者更好地组织和管理代码。访问对象属性是面向对象编程中最基本的操作之一...