java基础:所有参数皆是按值参数
c#中对于参数的传递,有二种处理方式,默认情况下:值类型的参数,按值传递(即:方法体内的参数是原值的副本);引用类型的参数,"加ref关键字后“,按引用传递(即:方法体内的参数,是对象的指针引用,在方法体内修改了对象的属性,方法调用完成后,这种变化也会保持下去).
java虽然也是OO语言,但是这一点有很大不同,不管是“值”类型的简单参数(比如:int),还是“引用”类型的对象参数(比如:Object),参数永远是按值传递(参数永远是原值的副本)。只不过,对于int型的简单参数,比如:5,副本也是5,相当于在内存又开辟一块空间,存储5这个值,但这二个5完全不相关联。而对于对象参数(比如:Object),参数副本应理解成对象指针引用“地址值”的副本,比如:原Object对象在内存中的指针地址为OX0001,则参数为OX0001的另一个副本,因为这二个地址值相同,所以在大多数情况下,方法体内,通过指针地址定位到的对象是同一个,即:方法体内修改对象的属性,该对象就被永远修改了,即使方法调用完成,这种修改的结果也会永远保存下去。这给很多java初学者造成java中参数有按引用传递的错觉。
看下面的示例:
先定义一个测试用的Person类
package com.cnblogs.yjmyzz.test; public class Person { public Person(){} private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String toString() {
return "name:" + name;
} }
然后来一个单元测试
@Test
public void testPerson1() { Person p1 = new Person();
p1.setName("aaa");
System.out.println(p1); // aaa
System.out.println(); changePerson1(p1);// xxx
System.out.println(p1);// xxx } void changePerson1(Person p) {
p.setName("xxx");
System.out.println(p);
System.out.println();
}
运行结果:
name:aaa
name:xxx
name:xxx
如上图所示,这种情况很好理解,p1,p因为值相同,所以根据这个地址值,寻址找到的对象是同一个,改p.name值与改p1.name没什么分别
再来一个版本:
@Test
public void testPerson2() throws InstantiationException,
IllegalAccessException { Person p1 = new Person();
p1.setName("aaa");
System.out.println(p1); // aaa
System.out.println(); changePerson2(p1);// yyy
System.out.println(p1);// xxx
} void changePerson2(Person p) throws InstantiationException,
IllegalAccessException {
Person newPerson = Person.class.newInstance();
newPerson.setName("yyy"); p = newPerson; System.out.println(p);
System.out.println();
}
运行结果:
name:aaa
name:yyy
name:aaa
如上图,刚开始P1,P值相同,但是在ChangePerson2内部,又new了一个Person的新实例:newPerson,修改newPerson.Name,并不会影响P1和P,在最后,将newPerson赋值给p,注意:p只是p1的地址值副本,所以虽然p与newPerson最终指向一样了,但是并不会影响原值p1,所以方法调用完成后,p1.name还是原来的值
java基础:所有参数皆是按值参数的更多相关文章
- java 基础:方法调用中的值传递是call by value,并且传递的是参数的值的拷贝,而不是引用
public class TestExtends { public static void main(String[]args){ int s = 10; System.out.println(Sys ...
- Java基础——引用类型作为形参与返回值
一.具体类名作为形参与返回值 1.方法的形参是类名,其实需要的是该类的对象 比如有一个具体的猫类,我使用另一个类使用猫类的方法 public class CatOperator { public ...
- [java基础] 遇到的一个关于返回值泛型的问题
在写代码的时候这样写: import java.util.ArrayList; import java.util.List; public class TestConversion { public ...
- Java基础学习-一切皆为对象
一切皆为对象 引用 String s; //s是引用,并不是对象. String s = "asdf" //创建一个引用的同时便进行初始化
- 【Java】 参数的传递:值传递与引用传递讨论
内容稍多,可直接看第4点的讨论结果 前言 在涉及到传递参数给方法时,容易出现一些参数传递错误的问题,这就涉及到了参数的传递问题,必须搞清楚:参数是如何传递到方法中的?一般来说,参数的传递可以分为两种: ...
- 067 01 Android 零基础入门 01 Java基础语法 08 Java方法 05 数组作为方法参数
067 01 Android 零基础入门 01 Java基础语法 08 Java方法 05 数组作为方法参数 本文知识点:数组作为方法参数 说明:因为时间紧张,本人写博客过程中只是对知识点的关键步骤进 ...
- 065 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 带参无返回值方法
065 01 Android 零基础入门 01 Java基础语法 08 Java方法 03 带参无返回值方法 本文知识点:带参无返回值方法 说明:因为时间紧张,本人写博客过程中只是对知识点的关键步骤进 ...
- 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值
接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...
- java解析出url请求的路径和参数键值对类 - 转
import java.util.HashMap; import java.util.Map; public class CRequest { /** * 解析出url请求的路径,包括页面 * @pa ...
随机推荐
- 面试问题4:C语言预处理包括哪些
问题描述:C语言 预处理包括哪些操作 C语言的三种预处理包括:宏定义(#define).文件包含(#include).条件编译(#if.#else.#endif). 对于宏定义的介绍: 宏定义必须写在 ...
- 【转】OpenStack和Docker、ServerLess能不能决定云计算胜负吗?
还记得在十多年前,SaaS鼻祖SalesForce喊出的口号『No Software』吗?SalesForce在这个口号声中开创了SaaS行业,并成为当今市值460亿美元的SaaS之王.今天谈谈『No ...
- 网站添加数据出错,原来是MS SQL Server2008日志文件占据空间过大导致的
最近发现公司上线的八爪鱼招标网有部分功能出现问题,主要表现为无法向数据库插入数据:远程登陆到数据库服务器时,发现原本的40G空间都被数据库吃完了,于是打开MS SQL Server 2008对数据库进 ...
- ORA-00030: User session ID does not exist.
同事在Toad里面执行SQL语句时,突然无线网络中断了,让我检查一下具体情况,如下所示(有些信息,用xxx替换,因为是在处理那些历史归档数据,使用的一个特殊用户,所以可以用下面SQL找到对应的会话信息 ...
- SQL Server 2000:提示“未与信任SQL SERVER连接相关连”错误
在使用“用户模式”登陆SQL Server 2000时提示“未与信任SQL SERVER连接相关连”错误,因为在安装SQL Server时选择“仅Windows”模式,所以所有用户都不可以登陆. 解决 ...
- 按要求编写Java应用程序。 (1)创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)、减速(车速自减)、修改车牌号,查询车的载重量。 编写两个构造方法:一个没有形参,在方法中将车牌号设置“XX1234”,速 度设置为100,载重量设置为100;另一个能为对象的所有属性赋值; (2)创建主类: 在主类中创建两个机动车对象。 创建第
package com.hanqi.test; public class jidongche { private String chepaihao;//车牌号 private int speed;// ...
- 编写Java应用程序。首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能
package com.hanqi.test; //银行账号 public class account { private String zhanghao;//账号 //私有余额 private do ...
- System V IPC(3)-共享内存
一.概述 1.共享内存允许多个进程共享物理内存的同一块内存区. 2.与管道和消息队列不同,共享内存 ...
- 报表开发工具中开放的部分图表js接口列表
1.. 描述 报表开发工具FineReport 8.0版本中开放了部分图表js接口,在具体应用的过程中很多人都不知道这些接口到底有什么作用,该怎么应用,所以根据我自己的应用在下面归纳了这些新开放js接 ...
- Windows Azure Redis 缓存服务
8月20日,Windows Azure (中国版)开始提供Redis缓存服务,比较国际版的Microsoft Azure晚了差不多一年的时间.说实话,微软真不应该将这个重要的功能delay这么长时间, ...