关于java传参

有一个比较经典的例子,如果你能说出此题的结果,说明你是java内存解析能手:

public class Test1 {
  public static class ParamTest {
   // 初始值为0
   protected int num = 0;
   // 为方法参数重新赋值
   public void change(int i) {
   i = 5;
   }
   // 为方法参数重新赋值
   public void change(ParamTest t) {
   ParamTest tmp = new ParamTest();
   tmp.num = 9;
   t = tmp;
   }
   // 改变方法参数的值
   public void add(int i) {
   i += 10;
   }
   // 改变方法参数属性的值
   public void add(ParamTest pt) {
   pt.num += 20;
   }
   public static void main(String[] args) {
   ParamTest t = new ParamTest();
   System.out.println("参数--基本类型");
   System.out.println("原有的值:" + t.num);
   // 为基本类型参数重新赋值
   t.change(t.num);
   System.out.println("赋值之后:" + t.num);
   // 为引用型参数重新赋值
   t.change(t);
   System.out.println("运算之后:" + t.num);
   System.out.println();
   t = new ParamTest();
   System.out.println("参数--引用类型");
   System.out.println("原有的值:" + t.num);
   // 改变基本类型参数的值
   t.add(t.num);
   System.out.println("赋引用后:" + t.num);
   // 改变引用类型参数所指向对象的属性值
   t.add(t);
   System.out.println("改属性后:" + t.num);
   }
   }
 }

输出结果:

参数--基本类型 原有的值:0 赋值之后:0 运算之后:0

参数--引用类型 原有的值:0 赋引用后:0 改属性后:20

这次听取高手建议,画一个内存图试试:

通过内存图,我们可以很清楚地看到,t.num的值始终都是0,到最后执行add(ParamTest pt)之后其值才变成20,至于前面的三个方法执行的结果都是针对简单变量,或其他对象的num属性,要理解这个例子,我觉得理解参数变量的传值机制很重要,参数是简单变量,则采用值传递,是引用类型变量,则采用引用地址传递。因此,我们可以看到,在执行change(t.num)与add(t.num)之后,t所指向对象的num属性并未发生变化,因为这是值传递,t.num值赋给i,方法对i进行操作,这并不改变num属性。而add(ParamTest pt)与change(ParamTest pt)采用引用传递,方法对传入的引用所指向的对象进行操作。

内存图画得似乎不是很详细,希望和有兴趣的人多多交流。

原文发布于微信公众号 - java达人(drjava)

原文发表时间:2016-01-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发与安全

从零开始学C++之构造函数与析构函数(一):构造函数、析构函数、赋值与初始化、explicit关键字

一、构造函数、默认构造函数 (1)、构造函数 构造函数是特殊的成员函数 创建类类型的新对象,系统自动会调用构造函数 构造函数是为了保证对象的每个数据成员都...

29100
来自专栏desperate633

深入理解javascript中的继承机制(1)原型链继承机制将共有的属性放进原型中

javascript中的继承机制是建立在原型的基础上的,所以必须先对原型有深刻的理解,笔者在之前已经写过关于js原型的文章。

8520
来自专栏机器学习从入门到成神

C++中重载、重写(覆盖)的区别实例分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

12230
来自专栏Flutter入门

Kotlin中apply,run,let,also,with函数总结

run函数和apply函数很像,只不过run函数是使用最后一行的返回,apply返回当前自己的对象。

34920
来自专栏Java后端技术

java中带继承类的加载顺序详解及实战

  在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么...

11320
来自专栏玄魂工作室

Python学习:类和实例

-----------------------------------------------------

18330
来自专栏从流域到海域

《Java程序设计基础》 第7章手记

本章主要内容 - 类的私有成员与公共成员 - 方法的重载 - 构造方法 - 类的静态成员 - 对象的应用 本节课知识性内容很多,这里...

19490
来自专栏纯洁的微笑

一个高频面试题,考考大家对 Java String 常量池的理解。

作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串...

23520
来自专栏架构之路

Java中Class类详解、用法及泛化

Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI。这项信息纪录了每个对象所属的...

33860
来自专栏Jack的Android之旅

疯狂Java笔记之面向对象的陷阱

instanceof是一个非常简单的运算符。instanceof运算符的前一个操作数通常是一个引用类型的变量,后一个操作数通常是一个类(也可以是接口,可以把接口...

9720

扫码关注云+社区

领取腾讯云代金券