这几天重构项目代码遇到一个疑问:可不可以在方法A中定义一个boolean变量b为false,然后A调用方法C把b传递到C方法中经过一些列业务判断后修改为true,C执行结束后A方法中b的值还是原来的false而并不会取到C方法修改后的true(当然实际业务并不是这样写,只是有这个疑问)。

查了一下资料,结论是这关系到Java方法传递参数是传值还是传址,方法执行的时候会不会拷贝副本再使用的问题。

回答是 ①Java方法传递传值不传址;②参数传递到方法之后会先进行一份拷贝,方法中使用的是参数的拷贝而参数本身。

示例代码如下:

import domain.User;

/**
* @author cc
* java 方法执行时传参数是传值,然后拷贝一个副本,方法中修改的是拷贝的副本,并不是值本身
*
* 当参数是引用类型时,传的值是引用的值,不是对象的值。拷贝一份引用的副本,副本的值和原来的值相等
* 也就是说副本指向的对象和原值指向的是同一个对象
*/
public class PassValueTest
{ public static void main(String[] args)
{
PassValueTest p = new PassValueTest();
final int i = 1;
boolean b = true; System.out.println("===测试int类型参数会拷贝副本后使用" );
System.out.println("原来i=" + i);
p.changeI(i);
System.out.println("在调用changeI之后 i = " + i);//i的值没有被改变
System.out.println(); System.out.println("===测试boolean类型参数会拷贝副本后使用" );
System.out.println("原来b=" +b);
p.changeB(b);
System.out.println("在调用changeB之后b = " + b);
System.out.println(); System.out.println("===测试引用类型参数传递的是引用的值并拷贝副本后使用 ");
User user = new User("dd", 28);
p.changeUser(user);
System.out.println("在调用ChangeUser方法之后user:" + user);
System.out.println(); System.out.println("===测试引用类型参数传到方法里面后是否会被先拷贝副本");
User userA = new User("userA", 10);
User userB = new User("userB", 12); p.changeCopy(userA, userB); System.out.println("在调用changeCopy方法之后,实际上userA和userB并没有改变:userA: " + userA
+",userB:" + userB);//实际上userA 和userB的引用并没有被改变
System.out.println("如果在方法中没有拷贝参数而直接使用参数的话,userA和userB的引用应该会像在方法中被调换的");
}
public int changeI(int i)
{
i = i+2;
System.out.println("在changeI方法中修改后i副本= " + i);
return i;
}
public boolean changeB(boolean b)
{
b = false;
System.out.println("在changeB方法中修改后b副本= " + b);
return b;
} public void changeUser(User user)
{
System.out.println("在changeUser方法中,user参数副本指向的对象和user参数指向的对象是同一个对象,修改前user:" + user);
user.setName("cici");
user.setAge(18);
System.out.println("在changeUser方法中,修改了参数副本所指向对象的值,修改后user:" + user);
} public void changeCopy(User userA,User userB)
{
System.out.println("在方法changeCopy中UserA和UserB的引用副本在修改前是 ,userA副本 :"
+ userA +", userB副本 : " + userB);
User temp = userA;//把A引用副本赋值给temp,就是说temp引用指向A对象
userA = userB;//把B引用副本赋值给A引用副本,就是说此时A引用副本指向B对象
userB = temp;//把temp引用赋值给B引用副本,就是说此时B引用副本指向A对象 System.out.println("在方法changeCopy中UserA和UserB的引用副本已经被调换 ,userA副本 :"
+ userA +", userB副本 : " + userB);
}
}

用到的User类:

 package domain;

 public class User {
private String name;
private int age; public User(String name,int age) {
this.name = name;
this.age = 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;
} @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("[").append(name).append(", age=").append(age)
.append("]");
return builder.toString();
} }

运行结果:

Java方法传递参数传值还是传址的问题的更多相关文章

  1. 一段代码让你秒懂java方法究竟是传值还是传地址

    先看看代码以及执行结果: 凝视写得非常清楚了.我就不多说了. 我说说我的结论.事实上在java中没有传值还是传址的概念,java仅仅有引用的概念.引用类似传址.只是是一个变量名中保存着对象的地址,地址 ...

  2. JAVA方法传递参数:传值?传引用?

    先来看下面这三段代码: //Example1: public class Example1 { static void check(int a) { a++; } public static void ...

  3. Python 传值和传址 copy/deepcopy

    传值:被调函数局部变量改变不会影响主调函数局部变量 传址:被调函数局部变量改变会影响主调函数局部变量 Python参数传递方式:传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值:如 ...

  4. java方法中,传参是传值还是传址问题(对比C语言、C#和C++)

    问题引出: 编写一个简单的交换值的小程序,如果我们只是简单地定义一个交换函数接收两个数,在函数内部定义一个中间变量完成交换.那么当我们把a,b两个实参传给这个函数时,往往得不到预期的结果.这是为什么呢 ...

  5. Java传值和传址

    调用函数时,传的参数过去可能是传值,也可能是传址.如果是传值,函数内部的操作对参数的值没有影响:如果是传址,函数内部的操作是对参数指向的内存进行操作,会影响参数的值. Java到底是传值还是传址?用下 ...

  6. javascript的变量,传值和传址,参数之间关系

    先把收获晾一下: 1.javascrip变量包含两种类型的值,一种为引用类型的值,一种是基本类型的值.引用类型包括:Array,Object,Function(可以这么理解,非基本类型的都是引用类型) ...

  7. Java方法的参数传递方式为: 值传递

    Java方法的参数传递方式为: 值传递 对于基本数据类型作为参数传递时, 是"按值传递", 这点都认识很清楚. 但是, 当对象或者说引用作为参数传递, Java 的参数传递方式是& ...

  8. JAVA传值与传址

    要了解JAVA中的传值与传址问题,必要先要了解JVA中的栈内存和堆内存,>>>>点些查看<<<<昨天写的学习记录 栈:基本数据类型.数据的引用变量,这两 ...

  9. javascript . 05 json的组成、for...in 遍历对象、简单数据类型与复杂数据类型的传值与传址、内置对象

    对象字面量  JSON var obj = { aaa :999}; var json={"aaa":999,"bbb":888}; "kay&quo ...

随机推荐

  1. bzoj 3365: [Usaco2004 Feb]Distance Statistics 路程统计【容斥原理+点分治】

    统计在一个root下的两个子树,每个子树都和前面的运算一下再加进去对于这种需要排序的运算很麻烦,所以考虑先不去同子树内点对的算出合法点对个数,然后减去每一棵子树内的合法点对(它们实际上是不合法的,相当 ...

  2. bzoj 2435: [Noi2011]道路修建【树形dp】

    dp求size和deep,然后对每条边模拟求代价即可 #include<iostream> #include<cstdio> #include<algorithm> ...

  3. oatu2.0认证原理(转)

    今天有时间总结一下: 一.OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 在详细讲解OAuth 2.0之前,需要了解几个专用名词,理 ...

  4. Hexo瞎折腾系列(2) - 添加背景图片轮播

    动态背景图片插件jquery-backstretch jquery-backstretch是一款简单的jQuery插件,可以用来设置动态的背景图片,以下是官方网站的介绍. A simple jQuer ...

  5. Codeforces Round #544 (Div. 3) C. Balanced Team

    链接:https://codeforces.com/contest/1133/problem/C 题意: 给n个数, 在这n个数中选最多n个数,来组成一个队伍. 保证这n个数的最大最小差值不大于5. ...

  6. 【C#】为什么有可能会被多个线程修改的对象要加线程锁

    例1.不用线程锁的情况下,两个线程对同一个变量进行加减操作 static void Main(string[] args) { Counter counter = new Counter(); var ...

  7. AJPFX总结jvm运行时内存分布

    jvm的运行过程中将java程序运行时数据区分为以下几个部分:      (1)程序计数器:存储虚拟机字节码执行的地址 (2)java虚拟机栈:java方法运行时的局部变量表,操作数栈,方法出口等 ( ...

  8. hihocoder offer收割编程练习赛9 B 水陆距离

    思路: 宽搜,多个起点. 实现: #include <iostream> #include <cstdio> #include <algorithm> #inclu ...

  9. ES6学习笔记(5)----数值的扩展

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 数值的扩展 1.Number对象的扩展(1)javascript的全局函数isNaN,isFin ...

  10. ios 根据颜色生成图片,十六进制颜色。

    //颜色生成图片方法 - (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size { CGRect rect = CGRectMake ...