Java改变引用数据类型的值

在Java中,引用数据类型的数据传递的是值(地址)的拷贝

对于以下代码

class BirthDate {
private int day;
private int month;
private int year; public BirthDate(int d, int m, int y) {
day = d;
month = m;
year = y;
} public void setDay(int d) {
day = d;
} public void setMonth(int m) {
month = m;
} public void setYear(int y) {
year = y;
} public int getDay() {
return day;
} public int getMonth() {
return month;
} public int getYear() {
return year;
} public void display() {
System.out.println
(day + " - " + month + " - " + year);
}
} public class Test {
public static void main(String args[]){
Test test = new Test();
int date = 9;
BirthDate d1= new BirthDate(7,7,1970);
BirthDate d2= new BirthDate(1,1,2000);
test.change1(date);
test.change2(d1);
test.change3(d2);
System.out.println("date=" + date);
d1.display();
d2.display();
} public void change1(int i){
i = 1234;
} public void change2(BirthDate b) {
b = new BirthDate(22,2,2004);
} public void change3(BirthDate b) {
b.setDay(22);
}
}

上述是一个对生日对象进行初始化,并进行修改的程序。程序通过构造函数进行初始化,并尝试使用不同方法对对象存储的值进行修改。

Birthdate是一个引用数据类型,简单地用方法传递值不能改变对象存储的值,应该使用类Birthdate的特定方法setDay。

图解引用数据类型的值传递和内存变化

局部变量存储在栈内存中,对象的值存储在堆内存中,故进行初始化后,内存中的分布会呈现如下图

此时栈内存中存储了对象test、d1、d2的地址以及局部变量date的值,而堆内存中存储了d1的值和d2的值,由栈内存中d1和d2的地址指向堆内存中各自的值。

而当执行了下面程序段后

        test.change1(date);
/*
省略中间的代码
*/ public void change1(int i){
/*
尚未执行的代码
*/
}

此时内存如下图所示

在方法change1中,程序段在栈内存中为形式参数i分配了新的空间,并通过值传递将其赋值为date的值,也就是9。

当开始执行代码段

    public void change1(int i){
i = 1234;
}

形式参数i的值被改为1234,而date中的值并没有改变。

当change1方法执行完毕后,为局部变量所分配的空间全部消失,而date的值依然为9,修改失败。

继续执行change2

        test.change2(d1);
/*
省略中间的代码
*/ public void change2(BirthDate b) {
/*
尚未执行的代码
*/
}

此时内存如下图所示

系统在栈内存中开辟新的空间给b,并将对象d2的值(地址)传递给了形式参数对象b,使得b的地址指向了一个和d2地址指向相同的堆内存空间,也就是指向对象d2存储的值。看起来就要修改成功了,不是吗?

但当执行下面代码段

    public void change2(BirthDate b) {
b = new BirthDate(22,2,2004);
}

这时b的地址改为指向新new出来的对象,内容悄然发生改变。

当change2方法执行完毕后,为局部变量所分配的空间全部消失,存储在堆内存中的值也会在一段时间后被垃圾回收机制回收,而d2的值并没有发生变化,修改依然失败。

最后看change3代码段

        test.change3(d2);
/*
省略中间的代码
*/ public void change3(BirthDate b) {
/*
尚未执行的代码
*/
}

类似于change2,系统给形式参数b分配了空间,指向d2对象的值

接下来执行setDay方法

    public void setDay(int d) {
day = d;
}
/*
省略中间的代码
*/
public void change3(BirthDate b) {
b.setDay(22);
}

setDay是类Birthdate中的方法,调用setDay方法后,会将setDay(int d)中的形式参数d传递给day这个成员变量,反映在内存中就是b的属性day变为22,由于b和d2在堆内存中所指向的是同一块内存空间,所以修改成功。

最后b这块内存消失,此时Birthdate对象d2的值已经发生改变。

Java改变引用数据类型的值的更多相关文章

  1. Java Object 引用传递和值传递

    Java Object 引用传递和值传递 @author ixenos Java没有引用传递: 除了在将参数传递给方法(或函数)的时候是"值传递",传递对象引用的副本,在任何用&q ...

  2. java的引用数据类型,你知道吗???

    有些人很清楚java的八种基本数据类型,但说到java的引用数据类型就不清楚了. Java的数据类型分为两大类,即基本数据类型和引用数据类型,在基本数据类型中有8种 基本数据类型(逻辑型-boolea ...

  3. java基础-引用数据类型之一维数组(Array)

    java基础-引用数据类型之一维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的定义 1>.为什么需要数组 保存一个数据可以定义一个变量,如果要保 ...

  4. java基础-引用数据类型之二维数组(Array)

    java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...

  5. Java基础-引用数据类型之集合(Collection)

    Java基础-引用数据类型之集合(Collection) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么出现集合类 面向对象语言对事物的体现都是以对象的形式,所以为了方便 ...

  6. Java 基础 引用数据类型 ArrayList集合

    引用数据类型(类) 分类 提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类.Random类. 我们可以把类的类型为两种: 第一种,Java为我们提供好的类,如Scanner类, ...

  7. Java 基础 引用数据类型 和 流程控制

    引用数据类型 与定义基本数据类型变量不同,引用数据类型的变量定义及复制有一个相对固定的步骤和格式: 数据类型 变量名 = new 数据类型(); 如:String st = new String(); ...

  8. Java容器-引用数据类型排序+TreeSet、TreeMap底层实现

    目录 1.冒泡排序的实现 2.比较接口(普通数据类型.引用数据类型) 普通数据类型:冒泡排序 引用数据类型:包装类(Integer.String.Character.Date) 自定义类型:实体类:i ...

  9. java 使用 引用数据类型(以Scanner、Random模块为例)

    创建一个新变量 类型 变量名 = new 类型() 举个例子: Scanner sc = new Scaner() 使用引用数据类型中的功能: 变量.功能名字() Scanner类:接受键盘输入 1. ...

随机推荐

  1. 07_TypeScript命名空间

    命名空间:内部模块,主要用于组织代码,避免命名冲突. 关键字:namespace //俩个类命名冲突 class Dog{ name: string; constructor(name: string ...

  2. vue中子组件触发父组件的方法

    网上找了几种方法,下面这两种最实用,最明了 方法一:父组件方法返回是字符串或数组时用这种方法 子组件: <template> <button @click="submit& ...

  3. 西门子S7comm协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析S7comm所含功能码以及UserData功能

    又一次成为懒蛋了,标题就这么改了改又是一篇新文章. 网上也有很多S7comm协议的解析,但还是如同我上一篇一样我只是做报文的解析对于S7comm的原理并进行阐述. 有些地方有错误的地方尽请大家指出,共 ...

  4. pycharm(迅雷下载链接)

    pycharm2020迅雷下载链接: https://download.jetbrains.com/python/pycharm-professional-2019.3.3.exe?_ga=2.146 ...

  5. echarts配置环形饼图的参数,以及牵引线显示百分比,中间数据

    最近项目有多处是用echarts的,有环形图,折线图,饼图,总结了一下. 本次主要讲环形图,折线图在下期. 这个是最终的效果图.下面附上代码 //三种占比 var myChartType = echa ...

  6. 初识Idea,部署Maven项目常见问题解决方案

    一.idea 中项目右键没有run命令选项,没有maven的clean与install选项 解决方案:安装Maven Helper插件 二.Idea不识别java文件(类文件显示橙色) 解决方案: 第 ...

  7. 为什么我用Ipad Pro做电子笔记和看PDF电子书

    为什么我用Ipad Pro做电子笔记和看PDF电子书 Ipad做笔记的优点: 1.ipad整理的笔记可以随时修改,可以看PDF的书,2.纸质书很重携带不便3.ipad的可通过关键词搜索笔记内容 4.笔 ...

  8. BizCharts使用采坑教程

      了不起的BizCharts 最近项目的管理后台都在用阿里粑粑开源的管理框架Ant Design Pro,说真话,还是比较好用的.该框架内部也封装了一些图标插件,但是在最近的一个项目中发现,这些图标 ...

  9. java面试必问问题总结

    1. 自我介绍 2. get跟load的区别 3. 什么是重载,什么是重写 4. HashTable跟HashMap的区别 5. Jsp九大隐式对象 6. Forword和redirect 的区别 7 ...

  10. nvm Nodejs 版本管理器 安装及配置

    1.如果已安装nodejs请先卸载干净 nodejs:删除C:\Program Files\nodejs 文件夹 npm:删除C:\Users\{用户名}\AppData\Roaming\npm 文件 ...