Java参数按值传递?按引用传递

简介:

有时候在想,java在调用方法时候究竟是按值传递还是按引用传递,之前有人说是基本数据类型按值传递,引用类型按引用传递。一时间,似乎都有道理。

笔者在此不追究字眼上的辨别识字能力,把自己对这个问题的理解阐述一下,笔者不想说这是按值传递还是按引用传递,自己理解就好了吧,毕竟java会用才是王道。

先看一下下面的代码:


 
 
  1. package shb.java.testmemory; 
  2.  
  3. public class TestMeo { 
  4.  
  5.     /**测试基本数据类型以及引用类型参数按值传递 
  6.      * @Description: 
  7.      * @author shaobn 
  8.      * @param args 
  9.      * @Date:2015-9-8 上午7:53:56  
  10.      */ 
  11.     public static void main(String[] args) { 
  12.         // TODO Auto-generated method stub 
  13.         testInt(); 
  14.         testStr(); 
  15.         testPack(); 
  16.         testObj(); 
  17.         testObj_2(); 
  18.     } 
  19.     //NO1.测试基本数据类型 
  20.     public static void testInt(){ 
  21.         int num1 = 12
  22.         System.out.println("Before change::"+num1); 
  23.         changeInt(num1); 
  24.         System.out.println("After change::"+num1); 
  25.     } 
  26.     //测试字符串类型 
  27.     public static void testStr(){ 
  28.         String str = "helloworld"
  29.         System.out.println("Before change::"+str); 
  30.         changeStr(str); 
  31.         System.out.println("After change::"+str); 
  32.          
  33.     } 
  34.     //测试包装类型 
  35.     public static void testPack(){ 
  36.         Integer integer = new Integer(42); 
  37.         System.out.println("Before change::"+integer); 
  38.         changePack(integer); 
  39.         System.out.println("After change::"+integer); 
  40.     } 
  41.     //测试引用类型 
  42.     public static void     testObj(){ 
  43.         Person person = new Person(); 
  44.         System.out.println("Before change::"+person.age); 
  45.         changeObj(person); 
  46.         System.out.println("After change::"+person.age); 
  47.     } 
  48.     //测试引用类型方式二 
  49.     public static void     testObj_2(){ 
  50.         Person person = new Person(); 
  51.         System.out.println("Before change::"+person.age); 
  52.         changeObj_2(person); 
  53.         System.out.println("After change::"+person.age); 
  54.     } 
  55.     public static void    changeInt(int num){ 
  56.         num = 21
  57.     } 
  58.     public static void     changeStr(String str){ 
  59.         str = "hellobeijing"
  60.     } 
  61.     public static void     changePack(Integer integer){ 
  62.         integer = new Integer(89); 
  63.     } 
  64.     public static void     changeObj(Person person){ 
  65.         person.age = 87;     
  66.     } 
  67.     public static void     changeObj_2(Person person){ 
  68.         person = new Person(); 
  69.         person.age = 78
  70.     } 
  71. //引用类型测试类 
  72. class Person{ 
  73.     public  int age = 78

Look NO1:

 

   

说明一下:笔者在上面画的两张图着实不咋样,只能做到这种程度了。我们分析一下:当数据为基本数据类型时,我们传给形参的仅仅是一个实参的副本(Copy),当然由于栈内存变量共享的特征,这两个变量共同指向此变量值。

当我们对形参进行改变时,首先,在栈内存中会寻找是否存在新的变量值,如果有,则指向新的变量值(体现栈内存数据共享的特点)。如果没有的话,在栈内存中回开辟一块空间,存储新的变量值,同时形参变量会指向新的变量值。

此时我们发现,这时的变量值已经与实参的变量没有关系,两个独立的变量。所以经过函数后改变的变量值与之前的没有关系,故输出的还是之前的变量值。

另外,我们看到,当传递对象的引用时,person引用变量中存储的是Person对象在堆内存中的内存地址,所以传递的是内存地址(笔者理解为是一串数字)。此时两个形参变量是有共同的内存地址值,所以指向同一个内存对象。我们观察

发现,当我们改变对象中的属性值时,有牵一发而动全身的感觉,只要你改变这个对象,这个对象就被改变,而不存在另外开辟一个对象的概念(String类型和包装类型除外)。

PS:还没有写完,正在上班时间,晚上再写吧!

如有错误,请大家帮忙纠正一下。


来源:51CTO

相关文章
|
2月前
|
Java
实现java执行kettle并传参数
实现java执行kettle并传参数
30 1
|
2月前
|
Java
在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
|
3月前
|
存储 算法 Java
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题
这篇文章是关于如何在Java中使用Graphics2D的RenderingHints方法来提高海报制作的图像质量和文字清晰度,包括抗锯齿和解决文字不清晰问题的技术详解。
82 0
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题
|
3月前
|
Java
java构造方法时对象初始化,实例化,参数赋值
java构造方法时对象初始化,实例化,参数赋值
89 1
|
5月前
|
Java
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
【Azure 应用服务】如何查看App Service Java堆栈JVM相关的参数默认配置值?
|
5月前
|
C# 开发者 Windows
震撼发布:全面解析WPF中的打印功能——从基础设置到高级定制,带你一步步实现直接打印文档的完整流程,让你的WPF应用程序瞬间升级,掌握这一技能,轻松应对各种打印需求,彻底告别打印难题!
【8月更文挑战第31天】打印功能在许多WPF应用中不可或缺,尤其在需要生成纸质文档时。WPF提供了强大的打印支持,通过`PrintDialog`等类简化了打印集成。本文将详细介绍如何在WPF应用中实现直接打印文档的功能,并通过具体示例代码展示其实现过程。
440 0
|
5月前
|
缓存 前端开发 Java
【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)?
【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)?
|
5月前
|
Java
java是值传递还是引用传递
本文澄清了Java中参数传递的常见误解,总结出Java采用“值传递”的方式。对于基本类型,传递其值的拷贝,方法内修改不影响原值;而对于对象类型,则传递其引用地址的拷贝,尽管是拷贝,但因指向同一对象,故方法内的修改会影响原对象状态。形参仅在方法内部有效,而实参则是调用方法时传递的具体值。通过示例和比喻(如复刻仓库钥匙),形象地解释了值传递、引用传递及Java特有的“共享对象传递”概念,帮助理解不同情况下参数传递的行为差异。
|
5月前
|
Java
java中的值传递和引用传递
【8月更文挑战第3天】在Java中,值传递用于基本数据类型,传递的是值的副本,因此方法内的修改不影响原值;而引用传递用于对象和数组,虽传递的是引用的副本,但对对象内容的修改会影响原始对象。理解这两者对于正确处理方法调用及参数至关重要。
|
5月前
|
Java
java中的值传递和引用传递
【8月更文挑战第2天】在Java中,基本数据类型如`int`、`double`等采用值传递,传递的是变量值的副本,因此方法内的修改不影响原变量。对象类型则通过引用传递,传递的是对象引用的副本,允许方法内修改原对象。例如,对`StringBuilder`对象的修改会影响原始对象。