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

开发 后端
有时候在想,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:

    

 

    [[148217]]

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

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

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

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

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

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

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

责任编辑:王雪燕 来源: 博客园
相关推荐

2022-07-29 08:05:31

Java值传递

2009-08-17 14:48:44

Java参数传递机制

2019-04-17 13:48:19

JavaScript前端传递

2012-02-21 14:04:15

Java

2016-09-18 19:07:33

Java值传递引用传递

2023-11-15 09:14:27

Java值传递

2024-09-04 01:36:51

Java对象传递

2020-09-02 08:00:51

Java引用传递值传递

2017-12-05 08:53:20

Golang参数传递

2022-11-02 15:00:03

Java值传递引用传递

2010-07-26 13:13:33

Perl函数参数

2011-03-25 13:44:28

Java值传递

2021-04-13 07:51:24

JavaScript引用传递

2009-09-04 11:00:13

通过C#引用传递

2009-09-09 11:07:52

LINQ to SQL

2023-03-29 23:23:00

MyBatis参数框架

2010-09-10 09:55:13

SQL参数变量

2023-11-29 09:47:11

C++对象

2009-06-24 13:14:11

URL来传递参数JSF

2009-12-17 17:04:09

Ruby函数参数传递
点赞
收藏

51CTO技术栈公众号