【Java】探究Java方法的参数传递是值传递还是引用传递
测试思路
每个更改形参的方法,返回值都是void,不同方法的参数设置不同类型。
注意在方法内测地址的时候在改之前测一下,才能看出传入参数是不是传了地址。(注意反正OS的内存地址是虚拟的,JVM中的也是,掰扯不清的,所以就姑且按照JVM中的虚拟地址来考虑吧)
数组参数传递
private static void changeArray(int[] array) {Arrays.fill(array, 2);
}
数组的值改变了,但地址没变,是引用传递。
基本类型及其包装类的参数传递
private static void changeInt(int data) {data = 3;
}private static void changeInteger(Integer data) {data = 3;
}
无论是int还是Integer,没有返回值,所以外面的实参值没变。
对于基本类型,打印地址也能看出地址改了,是值传递。
对于包装类型,打印地址能看出地址没改,是引用传递。
由于hashCode()被重写了,所以可以用System.out.println(System.identityHashCode(data));
来看虚拟地址(当然不是真的地址啦)。
普通类参数传递
private static class Person {int id;String name;int age;Person(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';}
}private static void changePerson(Person data) {data = new Person(101, "Bob", 15);
}
是引用类型,也是引用传递。打印地址测试过,确实在new之前的虚拟地址与传入实参的虚拟地址一致。(想测地址就把@Override的toString()注释掉,再打印对象啊)
只改属性
private static void changePersonAttributes(Person data) {data.id = 101;data.name = "Bob";data.age = 15;
}
改了属性,打印结果改了,但是实际地址没改,说明是引用传递。
完整代码
部分打印地址的测试内容就删掉不附上了,感兴趣可以自测。
import java.util.Arrays;public class ReferenceTest {private static void changeArray(int[] array) {Arrays.fill(array, 2);}private static void changeInt(int data) {data = 144;}private static void changeInteger(Integer data) {data = 155;}private static class Person {int id;String name;int age;Person(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';}}private static void changePerson(Person data) {data = new Person(101, "Bob", 15);}private static void changePersonAttributes(Person data) {data.id = 101;data.name = "Bob";data.age = 15;}public static void main(String[] args) {int[] array = new int[5];System.out.println(Arrays.toString(array));changeArray(array);System.out.println(Arrays.toString(array));Integer a = 133;changeInteger(a);System.out.println(a);changeInt(a);System.out.println(a);Person p = new Person(100, "Sam", 10);System.out.println(p);changePerson(p);System.out.println(p);changePersonAttributes(p);System.out.println(p);}
}
测试结果
[0, 0, 0, 0, 0]
[2, 2, 2, 2, 2]
133
133
Person{id=100, name='Sam', age=10}
Person{id=100, name='Sam', age=10}
Person{id=101, name='Bob', age=15}
总结反思
其实自己也一直没搞明白Java的参数传递到底是值传递还是引用传递,网上说法众说纷纭,于是下定决心自己认真测一下。
按照JVM的虚拟地址来做测试,在整数测试的时候还考虑了整数缓存池,选了127以上的数。
个人认为,其实不能单纯利用返回值为void的函数运行后查看原值来判断是值传递还是引用传递。我选择在传完参数后的函数内测地址,地址一样就是引用传递,不一样就是值传递。
hashCode()一般包含了地址,但Integer的hashCode()则只是原值,得使用System.identityHashCode(data)来测。
emmm,接下来,讲讲结论orz
总结
- 基本类型是值传递
- 引用类型是引用传递,返回值为void的话未必能在外面看到改变。
- 引用类型对象重新被new了以后,看不到改变;但改变属性能看到改变。
- 数组也是引用类型,数组元素值的改变能在void方法外面测出来。
其实研究这个问题Real迷惑,如有不足还请指正!
Update on 2020.3.7
强调String这个问题,如果你简单地测试得到地址没变,这是不对的,涉及到String常量池等等……
因为我还不太会,所以回头再来补充orz
看来这篇文章可能有些我思虑不周(尚未涉猎)的地方啊,果然水深莫涉啊orz
【Java】探究Java方法的参数传递是值传递还是引用传递相关推荐
- java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java编程语言只有值传递参数. 当一个对象实 ...
- Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?...
<Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?> <Java中的值传递和引用传递> 原理知识: 如果参数类型是原始类型,那么传过来的就是这 ...
- Java中的参数传递,到底是值传递还是引用传递?
文章内容为转载,转载自公众号Hollis关于我要彻底给你讲清楚,Java就是值传递,不接受争辩的那种! 原文链接:我要彻底给你讲清楚,Java就是值传递,不接受争辩的那种! 知乎回答链接:Java 到 ...
- Java参数传递(值传递还是引用传递)
文章目录 基本类型和引用类型的区别 下面我们再来看看==的作用 值传递和引用传递的区别 基本类型作为参数传递 对象作为参数传递 关于String 参考资料 基本类型和引用类型的区别 int num = ...
- java中的就近原则、方法中值传递和引用传递的区别、什么是构造方法、this关键字用法、什么是封装
你知道java中的就近原则嘛? package com.Test.java; /*** * 在java里面有一个"就近原则"详情可以参照下面代码**/public class Ac ...
- java中的参数传递(只有值传递没有引用传递)
Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递).所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答. java中的数据类 ...
- 这一次,彻底解决Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
- Java值传递和引用传递详细说明(详细分析)
1. 形参与实参 我们先来重温一组语法: 形参:方法被调用时需要传递进来的参数,如:func(int a)中的a,它只有在func被调用期间a才有意义,也就是会被分配内存空间,在方法func执行完成后 ...
- Java值传递和引用传递详细说明
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
最新文章
- 沉浸式小说App获得200万美元投资
- [转载]深入理解JavaScript闭包(closure)
- 某pl/sql培训练习题
- SAP Spartacus User form通过label标签的实现原理
- java switch case怎么判断范围_【转】Java期末复习攻略!
- php教程目录,php基础入门篇-文件和目录操作_PHP教程
- numpy 最大值_第 85 天:NumPy 统计函数
- 从零开始编写深度学习库(二)FullyconnecteLayer CPU编写
- @开发者,这个 GitHub 项目可以褥羊毛!
- Mono喜迁新家-http://www.xamarin.com/
- 复杂UI的组织-创建者模式-uitableview思想
- Java编译出现不可映射字符
- Java实现 LeetCode 313 超级丑数
- ActiveMQ在win7下启动失败解决方案
- tp获取php异常信息,ThinkPHP 异常处理
- APP全栈工程师修炼之路(三)
- 微信“跳一跳”外挂制作历程
- 北京理工大学计算机科学与技术培养方案,王全玉_北京理工大学计算机学院
- fatal: unable to access ‘‘: Failed to connect to 27.0.0.1 port 7890 after 2097 ms:Connection
- nginx-quic