`
My*Love
  • 浏览: 72196 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

值传递与引用传递-内存解析

    博客分类:
  • JAVA
阅读更多
   以前自己就没怎么搞清楚值传递与引用传递的内部机制,近来发现好多面试题中都考到了它,决定真正弄懂它,所以在网上查了很多资料,最后再结合自己的理解,写一篇文件来做一下总结。

     这里就结合一个常见的例子来做解析,User类源码如下:

class User {
     private int id;
     private String name;

     public User(int _id, String _name) {
	       id=_id; 
            name=_name;
     }

     public void setId(int $id) {
            id=$id; 
     }

     public void setName(String  $name) {
            name=$name; 
     }

     public int getId() { 
            return id;	
     }

     public String getName() { 
           return name; 
     }

     public String toString() { 
           return id+" - "+name;
     }
}


     再写一个测试类UserTest:
public class UserTest {
	public static void main( String[] args) {
		UserTest test=new UserTest();
		int n=2;
		User u1=new User(20,"Boy");
		User u2=new User(21,"Girl");
		test. changeId (n);
		System.out.println ( "n is " + n);
		test.changeName(u1);
		test.changeIdName(u2);
		System.out.println(u1.toString());
		System.out.println(u2.toString());
	}
	public void changeId(int i) {  
              i=3;
         }
	public void changeName( User  u) {
	     u=new User(1,"Test");
	}
	public void changeIdName( User  u) {
		u.setId(23);  
          u.setName ("My Name");	
 	}
}


   为了真正弄清楚程序的执行过程,我觉得得先明白几个东西,也就是下面这张图里面的内容:

   
    下面再来讲解程序在内存中的执行过程,首先从main函数的第一行开始,创建了一个UserTest对象,变量test指向了新new出来的UserTest对象,通过上面知道,局部变量存放在栈空间,所以执行完这句,在栈中就给test变量分配了一小块空间,同时在堆内存中也分配了一块空间用来存放new出来的UserTest对象,test指向了堆中对象,这就是所谓的引用;再往下面给一个变量赋值,同样是一个变量,在栈中分配一块空间,变量名为n,类型为int,值为2;下面创建了一个User对象,栈中给u1变量分配空间,堆中也分配一块内存给new出来的User对象,同样u1也指向了堆中new出来的User对象,这个对象中有两个成员变量id和name,但创建这个对象的时候,我们调用了这个对象的有参构造方法:

public User(int _id,String _name) {
	 	id=_id;
	 	name=_name;
	}

那么方法是怎么执行的呢?方法里面的开参跟局部变量同等对待,在栈中分配_id和_name空间,它们的值分别是20和"Boy",然后通过赋值,就把它们的值传递给了User对象中的id和name,当这个方法构造方法调用完毕后,分配给这个方法的参数和内存全部消失,然后再给让其它人用。那么这个过程的执行流程图如下:

    
     我觉得这个内存的分析,对我们学习程序是很有帮助的,我相信只要弄懂了内存,以后这方面再怎么样的面试题都难不到了。另外还要强调的是:
     1.先要弄清程序存放在内存的哪些地方。
      2.局部变量的存放位置,尤其方法里面的参数,方法执行完毕,为这个方法分配的参数和内存都将消失,把空间让给别人用。
      3.新new出来的对象一定是放在堆中,如果一个对象没有了引用,也就会在适时被垃圾回收掉。
      4.这个东西最好是自己动手画一画,一动手可能就全明白了。

     由于程序执行是一个动态的过程,如果用语言描述清楚,需要花大量的篇幅,写了之后别人也不一定能看的懂,所以我做了一个PPT,比较全面的描述了这个程序在内存中的执行过程,不过由于本人PPT技术不咋的(呵呵),做的比较粗糙,希望大家都能看的懂。这篇文章是自己看过一些资料后的总结,自己难免会有理解疏漏的地方,希望大家不吝赐教。
  • 大小: 22.9 KB
  • 大小: 42.9 KB
3
2
分享到:
评论

相关推荐

    Java:按值传递还是按引用传递详细解说

    ### Java中的按值传递与按引用传递详解 #### 一、引言 在Java编程语言中,关于参数传递的方式一直存在两种观点:一种认为Java仅支持按值传递,另一种则指出Java同时支持按值传递和按引用传递。实际上,这两种观点...

    java值传递与引用传递

    因此,尽管看似是引用传递,但对`String`类型的处理结果与值传递类似。 总结来说,Java中的参数传递主要有以下特点: 1. 基本数据类型按值传递,函数内部无法改变实际参数的值。 2. 引用类型看似按引用传递,实际上...

    Delphi值传递和引用传递实例

    引用传递则不同,它不复制实参的值,而是传递实参的内存地址给形参。形参实际上是对实参的一个引用,因此对形参的任何修改都会直接影响到实参。在Delphi中,使用`var`关键字来声明引用参数: ```delphi procedure ...

    Java的按值传递和按引用传递分析.rar

    Java编程语言中有两种参数传递方式:按值传递和按引用传递。理解这两种方式对于编写高效、无误的代码至关重要。 1. **按值传递(Pass by Value)** - Java中的基本类型(如int, double, char等)是按值传递的。这...

    java 之方法调用 方法传参 值传递还是引用传递字节码

    本文将深入探讨Java中的方法调用、值传递与引用传递,并通过字节码分析来进一步理解这些概念。 首先,我们来看方法调用。在Java中,方法是一组完成特定任务的代码块,可以通过方法名来调用执行。方法调用的基本语法...

    值类型和引用类型的区别

    - 传递的是指向数据的引用,即按引用传递。 - 修改接收方的引用类型变量会影响原始变量。 #### 4. 示例分析 假设有一个简单的`Person`类,包含`Name`和`Age`两个属性,其中`Person`类和`Name`属性是引用类型,而`...

    Python中 传递值 和 传递引用 的区别解析

    接下来,我们详细分析Python中不可变类型和可变类型在传递值和传递引用时的行为: 1. 不可变类型: 在Python中,不可变类型包括数字(Number)、字符串(String)和元组(Tuple)等。不可变类型的对象一旦创建,它...

    论JS函数传参时:值传递与引用传递的区别

    首先讨论函数之前,先弄清楚基本类型值与引用类型值的复制问题 一、数据类型的复制分析 内存分为栈区(stack)和堆区(heap) ,如果将内存看成一本书,栈好比是书的目录,而堆就是书的内容,基本类型可以看成内容...

    C#文档冒泡排序,值传递与址传递

    值传递意味着将变量的值复制给函数参数,而引用传递则是传递变量的内存地址,使得函数可以直接访问和修改原始变量的值。 #### 值传递 当向函数传递基本类型(如`int`、`double`等)或值类型(如`struct`)的参数时...

    java按值传递还是按引用传递详细解说[收集].pdf

    通过上述分析,我们可以得出结论,尽管Java的参数传递方式被描述为“按值传递”,但对于对象来说,实际上传递的是对象引用的副本,从而实现了类似按引用传递的效果。理解这一机制对于编写Java程序至关重要,尤其是在...

    深入理解python中函数传递参数是值传递还是引用传递

    在探讨Python函数传递参数的方式时,很多人会陷入“值传递”与“引用传递”的概念之中。实际上,这两种说法在Python中并不完全适用,因为Python有自己的特殊机制来处理参数传递。本文将通过具体的代码示例和内存地址...

    浅谈JavaScript 函数参数传递到底是值传递还是引用传递

    然而,JavaScript的实现其实更为复杂,它包含了值传递和引用传递的特性,但并不完全等同于这两种方式。 首先,我们来看基础类型的参数传递。例如,对于一个数字`num`: ```javascript function add(num) { num +=...

    Windows Phone 8 -PhotoCamera-内存泄漏Demo

    4. **长时间持有相机引用**:在某些情况下,开发者可能会长时间保持对相机的引用,比如在多个页面之间传递相机实例。这会导致相机资源无法释放,直到应用完全关闭。 解决这些问题的方法包括: 1. **使用Using语句*...

    解析Java按值传递还是按引用传递

    按引用传递的重要特点是:传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。例如: ```java public class TempTest { private void test1(A a){ a.age = 20; System.out....

    浅析Java引用类型和方法参数传递

    - 当传递引用类型时,尽管仍然遵循按值传递的原则,但由于传递的是引用的值,因此对引用所指向的对象所做的任何修改都会影响原始对象。 - 在处理不可变类型(如 `String`)时,需要注意即使是引用类型,由于不可变性...

    Java中值传递和引用传递的区别

    本文将通过示例代码详细介绍Java中值传递和引用传递的区别,并对其进行深入分析。 一、值传递 值传递是一种常见的参数传递机制,在这种机制中,实参传递给形参的是值。形参和实参在内存上是两个独立的变量,对形参...

    解析java基本数据类型传递与引用传递区别

    Java中的参数传递方式有两种基本类型:按值传递和引用传递,但实际上Java只支持按值传递。这意味着在Java中,无论是基本数据类型还是引用数据类型,传递的都是值的一个拷贝。 对于基本数据类型(如int、char、float...

    winform 方法参数的引用传递源码

    2. 引用传递:与值传递不同,引用传递是将变量的内存地址传给方法,方法可以访问并修改原始变量的内容。在C#中,对象实例是通过引用传递的,因为它们的值实际上是内存中的地址。 在WinForm应用中,可能会有以下场景...

Global site tag (gtag.js) - Google Analytics