方法参数的值调用+引用调用+深浅拷贝
来源:互联网 发布:caffe bene菜单 编辑:程序博客网 时间:2024/05/16 08:01
【0】README
0.1)本文描述+源代码均 转自 core java volume 1, 旨在理清值调用+引用调用;
【1】参数传递给方法的专业术语:
1.1)值调用:它表示方法接收的是调用者提供的值;
1.2)引用调用:它表示方法接收的是调用者提供的变量地址;
【2】看个荔枝:
2.1)设一个方法视图将一个参数值增大3倍:
public static void tripleValue(double x){ x = 3 * x;}
2.2)然后调用这个方法:
double percent = 10; tripleValue(percent);
2.3)无论如何,调用这个方法后,percent的值还是10,下面看一下具体执行过程:
- step1) x 被初始化percent值的一个copy;
- step2) x 被乘以 3 后等于 30, 但是 percent 仍然是 10;
- step3) 这个方法结束后, 参数变量x 不在使用;
【3】方法参数共有两种类型:
- type1) 基本数据类型(数字、布尔值);
- type2) 对象引用;
3.1)可以看到, 一个方法不可能修改一个基本数据类型的参数;
3.2)对象引用作为参数就不同了,可以很容易地利用下面的方法实现将一个雇员的薪水提高两倍:
package com.corejava;public class EmployeeTest { public static void main(String[] args) { Employee e = new Employee(10); Employee.tripleSalary(e); System.out.println("salary = " + e.getSalary()); }}class Employee{ private double salary; public Employee(double salary) { this.salary = salary; } public static void tripleSalary(Employee e) { e.raiseSalary(200); } public void raiseSalary(double x) { this.salary = this.salary * x / 100; } public double getSalary() { return salary; } }打印结果为: salary=20.0
3.3)上述程序的具体调用过程为:
- step1) x 被初始化为 harry值的拷贝, 这里是一个对象的引用;
- step2) raiseSalary方法应用于这个对象引用, x 和 harry 同时引用的那个 Employee对象的薪水提高了200%;
- step3) 方法结束后,参数变量x 不再使用, 当然,对象变量harry继续使用那个薪水涨了 200%的对象;
3.4) 读者已经看到,实现一个改变对象参数状态的方法并不是难事, 方法得到的是对象引用的copy, 对象引用和其它的copy同时引用同一个对象;
【4】再看个荔枝:
package com.corejava;public class EmployeeTestOne { public static void main(String[] args) { EmployeeOne a = new EmployeeOne("Alice"); EmployeeOne b = new EmployeeOne("Bob"); System.out.println("before:" + a.getName() + b.getName()); EmployeeOne.swap(a,b); System.out.println("after:" + a.getName() + b.getName()); }}class EmployeeOne{ private String name; public EmployeeOne(String name) { this.name = name; } public static void swap(EmployeeOne x, EmployeeOne y) { EmployeeOne temp = x; x = y; y = temp; } public String getName() { return name; }}打印结果为:before:AliceBobafter:AliceBob
4.1)显然, 方法并没有改变存储在变量 a 和 b 中的 对象引用;swap 方法的参数x 和 y 被初始化为两个对象引用的copy, 这个方法交换的是 两个拷贝;在方法结束时参数变量x 和 y 被丢弃了, 原来的变量 a 和 b仍然引用这个方法调用之前所引用的对象;
4.2)这个过程说明: java程序设计语言对对象采用的不是引用调用, 实际上,对象引用进行的是 值传递;
【5】下面总结下 java 中方法参数的使用情况:
- 5.1)一个方法不能修改一个基本数据类型的参数(数值型和布尔型);
- 5.2)一个方法可以改变一个对象参数的状态;
- 5.3)一个方法不能让对象参数引用一个新的对象;
【6】最后一个综合性荔枝:
/** * This program demonstrates parameter passing in Java. * @version 1.00 2000-01-27 * @author Cay Horstmann */public class ParamTest{ public static void main(String[] args) { /* * Test 1: Methods can't modify numeric parameters */ System.out.println("Testing tripleValue:"); double percent = 10; System.out.println("Before: percent=" + percent); tripleValue(percent); System.out.println("After: percent=" + percent); /* * Test 2: Methods can change the state of object parameters */ System.out.println("\nTesting tripleSalary:"); Employee harry = new Employee("Harry", 50000); System.out.println("Before: salary=" + harry.getSalary()); tripleSalary(harry); System.out.println("After: salary=" + harry.getSalary()); /* * Test 3: Methods can't attach new objects to object parameters */ System.out.println("\nTesting swap:"); Employee a = new Employee("Alice", 70000); Employee b = new Employee("Bob", 60000); System.out.println("Before: a=" + a.getName()); System.out.println("Before: b=" + b.getName()); swap(a, b); System.out.println("After: a=" + a.getName()); System.out.println("After: b=" + b.getName()); } public static void tripleValue(double x) // doesn't work { x = 3 * x; System.out.println("End of method: x=" + x); } public static void tripleSalary(Employee x) // works { x.raiseSalary(200); System.out.println("End of method: salary=" + x.getSalary()); } public static void swap(Employee x, Employee y) { Employee temp = x; x = y; y = temp; System.out.println("End of method: x=" + x.getName()); System.out.println("End of method: y=" + y.getName()); }}class Employee // simplified Employee class{ private String name; private double salary; public Employee(String n, double s) { name = n; salary = s; } public String getName() { return name; } public double getSalary() { return salary; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; }}
0 0
- 方法参数的值调用+引用调用+深浅拷贝
- 方法参数的调用是值调用而不是引用调用
- java基础入门-方法参数的调用是值调用而不是引用调用
- 方法参数的调用是值调用而非引用调用
- Java方法参数是引用调用还是值调用?
- Java方法参数是引用调用还是值调用?
- 【解惑】Java方法参数是引用调用还是值调用?
- 【解惑】Java方法参数是引用调用还是值调用?
- Java方法参数是引用调用还是值调用?
- java 方法参数-值调用,引用调用问题
- 对象的深浅拷贝方法
- java方法传递参数传递的到底是什么?值调用:引用调用
- C++拷贝构造函数 调用时机 -- 深浅拷贝
- JavaDay03--Notes(数组的遍历和部分拷贝+方法的调用、参数和返回值)
- Java方法参数是引用调用还是值调用?——值调用
- 拷贝构造函数为何可以调用引用参数对象的私有成员?
- 函数调用中参数和返回值的拷贝
- C++(笔记)深浅拷贝and何时调用
- 九度OJ 1168:字符串的查找删除 (查找)
- Codeforces Round #327 (Div. 2) B. Rebranding
- 思考记录--聊天机器人
- eclipse maven tomcat插件安装截图
- tomcat中同时部署两个项目的异常解决
- 方法参数的值调用+引用调用+深浅拷贝
- Linux生成和使用so库
- 1017. A除以B (20)
- css3 media媒体查询器用法总结
- 解决IDEA任何改动都不自动编译的问题
- -1717986918
- Android--启动拍照功能并返回结果
- 九度OJ 1169:比较奇偶数个数 (基础题)
- 【PAT】1086. Tree Traversals Again (25)