值传递

在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。

先来看个例子:

public static void valueCross(int age,float weight) {
System.out.println("传入的age值:"+age);
System.out.println("传入的weight值:"+weight);
age=23;
weight=60;
System.out.println("修改后的age值:"+age);
System.out.println("修改后的weight值:"+weight);
} public static void main(String[] args) {
int age=10;
int weight=50;
valueCross(age,weight);
System.out.println("方法执行后的age:"+age);
System.out.println("方法执行后的weight:"+weight); }

  

运行结果:

传入的age值:10
传入的weight值:50.0
修改后的age值:23
修改后的weight值:60.0
方法执行后的age:10
方法执行后的weight:50

  

我们可以看到valueCross方法执行后,实参age和weight的值并没有发生变化,这是什么原因?

首先程序运行时,先从main方法开始执行,此时JVM为main()方法往虚拟机栈中压入一个栈帧,即为当前栈帧,用来存放main()中的局部变量表(包括参数)、操作栈、方法出口等信息,如a和w都是mian()方法中的局部变量,因此可以断定,age和weight是躺着mian方法所在的栈帧中

接着调用valueCross方法,此时JVM为valueCross()方法往虚拟机中压入一个栈帧,即为当前栈帧,用于存放valueCross方法的局部变量等信息;因此age和weight是躺着valueCrossTest方法所在的栈帧中,而他们的值是从a和w的值copy了一份副本而得,如图:

因此这两个age和weight对应的内容不是同一个,在valueCross方法中修改的只是自己栈中的内容,并没有修改main方法栈中的内容

引用传递

”引用”也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响的真实内容。

先有一个Person类代码如下:

public class Person {

	private String name;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} }

  

测试类代码:

public class TestArr {

	public static void PersonCross(Person person) {
System.out.println("传入的person的name:"+person.getName());
person.setName("敖丙");
System.out.println("方法内重新赋值后的name:"+person.getName());
} public static void main(String[] args) {
Person p=new Person();
p.setName("哪吒");
p.setAge(4);
PersonCross(p);
System.out.println("方法执行后的name:"+p.getName());
} }

  

测试结果1:

传入的person的name:哪吒
方法内重新赋值后的name:敖丙
方法执行后的name:敖丙

  

我们可以看到PersonCross方法执行后,person的name值被改变了

下面再看一段代码:

public class TestArr {
public static void PersonCross(Person person) {
System.out.println("传入的person的name:"+person.getName());
person=new Person();//新添加的代码
person.setName("敖丙");
System.out.println("方法内重新赋值后的name:"+person.getName());
} public static void main(String[] args) {
Person p=new Person();
p.setName("哪吒");
p.setAge(4);
PersonCross(p);
System.out.println("方法执行后的name:"+p.getName());
} }

  

测试结果2:

传入的person的name:哪吒
方法内重新赋值后的name:敖丙
方法执行后的name:哪吒

  

有没有发现什么不同,这次PersonCross方法执行后person的name值并没有改变,这又是为什么?

我们知道,java中的对象和数组是存放在堆内存中的,而堆内存是线程共享的,所以main方法执行时,会在堆内存中开辟一块内存,用来存储p对象的所有内容,然后再栈内存中创建一个引用p存储堆区中p对象的真实地址,如下图:

当执行到PersonCross方法时,因为方法内有这么一行代码:person=new Person(),此时JVM在堆内存中又开辟了一块内存空间,假设地址为xo2222,那么现在的person则指向了xo2222这块内存,现在修改person的name值修改的是xo2222这块内存空间的值,不会改变xo3333的值,所以测试结果2中的name没有发生变化

引用传递本质上就是值传递,将引用变量的值传递给形参,因为引用变量的值存放的是地址值,所以当地址值传递给形参后,形参和实参指向同一块内存区域。

java——值传递和引用传递的更多相关文章

  1. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  2. java中值传递和引用传递

    最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  3. Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

  4. java的值传递和引用传递

    昨天博主在对于值传递和引用传递这里栽了一个大坑啊,导致一下午时间都浪费在这里,我们先说下值传递和引用传递java官方解释: 值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对 ...

  5. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  6. java 对象传递 是 值传递 还是 引用传递?

    这个问题说实话我感觉没有太大的意义. 按第一印象和c++的一些思想去理解的话对象传递是引用传递,因为传递过去的对象的值能被改变. 但是又有很多人,不知道从哪里扣出来一句,java中只有值传递,没有引用 ...

  7. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  8. Java面向对象-方法的值传递和引用传递

    Java面向对象-方法的值传递和引用传递 0 发布时间:『 2016-08-21 14:21』  博客类别:Java核心基础  阅读(197) 评论(0) Java面向对象-方法的值传递和引用传递 方 ...

  9. Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结

    这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...

  10. Java值传递和引用传递

    Java总是在讨论是传递还是引用传递,Java没有像C语言那样拥有指针,在看到引用传递和值传递很多的解释之后,更相信引用传递和值传递归根到底都是值传递,只不过引用传递的时候看上去很高大上,其实是把变量 ...

随机推荐

  1. mysql转移Data目录

    本来很简单的事,为何这么复杂,转目录后经常不成功.mysql安装时就不能指定数据目录吗?老是默认在C盘 测试环境Windows10, mysql5.7,以下是测试记录: 1. 复制Data到D盘下,如 ...

  2. Hibernate 关系配置

    表之间关系 1. 一对多 一个部门有多个员工,一个员工只能属于某一个部门 一个班级有多个学生,一个学生只能属于一个班级 2. 多对多 一个老师教多个学生,一个学生可以被多个老师教 一个学生可以先择多门 ...

  3. Java 内存模型学习笔记

    1.Java类 public class Math { public static final Integer CONSTANT = 666; public int math(){ int a = 1 ...

  4. P5663 加工零件

    P5663 加工零件 题解 暴力搜索 搜索显然会TLE #include<iostream> #include<cstdio> #include<cstdlib> ...

  5. keras输出预测值和真实值

    在使用keras搭建神经网络时,有时需要查看一下预测值和真是值的具体数值,然后可以进行一些其他的操作.这几天查阅了很多资料.好像没办法直接access到训练时的数据.所以我们可以通过回调函数,传入新的 ...

  6. ISO/IEC 9899:2011 条款6.4.6——标点符号

    6.4.6 标点符号 语法 1.以下之一     [  ]    (  )     {  }    .    ->    ++    --    &    *    +    -     ...

  7. It’s worth noting值得注意的是

    It’s worth noting that in JavaScript applications the Model is often connected via Ajax to a back-en ...

  8. java-mybaits-012-mybatis-Interceptor-拦截器读写分离四种实现方案

    一.概述 基本项目搭建 技术框架:spring web mvc .日志[slf4j.log4j2].mybatis.druid.jetty插件启动.mybatis-generator逆向配置生产dao ...

  9. React——嵌入已有项目 && jsx

    Add React to a Website React has been designed from the start for gradual adoption, and you can use ...

  10. (一)深入java虚拟机之内存溢出与分析

    一.内存溢出程序 public class Test { public static void main(String[] args) { List<User> userList=new ...