按值调用表示方法接收的是调用者提供的值;而按引用调用表示方法接收的是调用者提供的变量地址;一个方法可以修改传递引用所对应的变量值, 而不能修改传递值调用所对应的变量值;

  Java语言对对象采用的是引用传递还是按值传递?下面举个例子说明;

public class ParamTest {

	public static void main(String[] args) {
System.out.println("---测试1 tripleValue---");
double percent = 10;
System.out.println("Before percent:" + percent);
tripleValue(percent);
System.out.println("After percent:" + percent); System.out.println("---测试2 tripleSalary---");
Employee harry =new Employee("Harry", 5000, 1);
System.out.println("Before salary:" + harry.getSalary());
tripleSalary(harry);
System.out.println("After salary:" + harry.getSalary()); System.out.println("---测试3 swap---");
Employee emp1 =new Employee("Alice", 1000, 1);
Employee emp2 =new Employee("Bob", 1000, 1);
System.out.println("Before emp1:" + emp1);
System.out.println("Before emp2:" + emp2);
swap(emp1, emp2);
System.out.println("After emp1:" + emp1);
System.out.println("After emp2:" + emp2); } public static void swap(Employee e1, Employee e2) {
Employee tmp = e1;
e1 = e2;
e2 = tmp;
} public static void tripleSalary(Employee x) {
x.setSalary(200);
System.out.println("End of method salary:" +
x.getSalary());
} public static void tripleValue(double x) {
x *= 3;
System.out.println("End of method x:" + x);
} }

  

  Employee实体类:

public class Employee {
private String name;
private double salary;
private int id; public Employee(String name, double salary, int id) {
this.name = name;
this.salary = salary;
this.id = id;
} public Employee() {
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getSalary() {
return salary;
} public void setSalary(double byPercent) {
     double raise = this.salary * byPercent / 100;
this.salary += raise;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary=" + salary +
", id=" + id +
'}';
}
}

  

  上面的测试代码的结果是:

---测试1 tripleValue---
Before percent:10.0
End of method x:30.0
After percent:10.0
---测试2 tripleSalary---
Before salary:5000.0
End of method salary:15000.0
After salary:15000.0
---测试3 swap---
Before emp1:Employee{name='Alice', salary=1000.0, id=1}
Before emp2:Employee{name='Bob', salary=1000.0, id=1}
After emp1:Employee{name='Alice', salary=1000.0, id=1}
After emp2:Employee{name='Bob', salary=1000.0, id=1}

  

  对于测试1,方法的参数为基本类型,一个方法试图将一个参数值增加至3倍,不过该方法调用后,percent的值还是10;它的执行过程(如下图):

    1 ) x 被初始化为 percent 值的一个拷贝;

    2) x被乘以 3后等于 30,但是percent仍然是10

    3 ) 这个方法结束之后,参数变量 X不再使用;

                  

   从测试1可以看出一个方法不可能修改一个基本数据类型的参数;

  

   对于测试2,方法的参数为对象的引用,具体的执行过程(如下图):

    1 ) X 被初始化为 harry 值的拷贝,这里是一个对象的引用;

    2 ) setSalary方法应用于这个对象引用,x 和 harry 同时引用的那个 Employee 对象的salary;

    3 ) 方法结束后,参数变量x不再使用,但是对象变量harry继续引用那个雇员对象;

    

    对于测试3,swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这个变量的拷贝(如下图):

          

   通过上面的测试说明,Java语言对对象采用的按值传递,而不是引用传递;

    • 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型);
    • 一个方法可以改变一个对象参数的状态;
    • 一个方法不能让对象参数引用一个新的对象;

参考:《Java核心技术卷一基础知识》的第4章第5节

最新文章

  1. Android Ormlite 学习笔记2 -- 主外键关系
  2. 启动CLR
  3. CWMP开源代码研究3——ACS介绍
  4. JQuery_DOM 节点操作之包裹节点
  5. C# 随机红包算法
  6. HDU4080 Stammering Aliens(二分 + 后缀数组)
  7. 安装 phoneGap
  8. 无状态服务(stateless service)
  9. 开发专题指南: JEECG高速微云开发平台前言
  10. c++链接数据库测试,中文有问题
  11. 链表的实现 -- 数据结构与算法的javascript描述 第六章
  12. Linux下安装Oracle11g服务器(转)
  13. 关于MVC结构
  14. omi-cli新版发布-升级webpack2和支持sass生成组件局部CSS
  15. Jmeter函数引用和函数重定向
  16. 2017寒假零基础学习Python系列之函数之 定义默认参数
  17. Nginx的知识分享,继续上次的分享
  18. Latex: "Missing $ inserted" 解决方法
  19. Math、Random、System、BigInteger、Date、DateFormat、Calendar类,正则表达式_DAY14
  20. poj 1511 Invitation Cards(最短路中等题)

热门文章

  1. CSS、bootstrap4等相关疑难杂症
  2. SpringBoot框架:快速入门搭建运行一个应用程序(一)
  3. 执行引擎(Execution Engine)基础知识
  4. Java 实现常见内排序
  5. 零基础小白必看篇:从0到1构建Python Web框架
  6. matlab中uicontrol创建用户界面控件
  7. P3118 [USACO15JAN]Moovie Mooving G
  8. P5664 Emiya 家今天的饭
  9. Geography's sum up
  10. JS/TS 对数组中的对象按对象的值进行去重