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

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

  1. public class ParamTest {
  2.  
  3. public static void main(String[] args) {
  4. System.out.println("---测试1 tripleValue---");
  5. double percent = 10;
  6. System.out.println("Before percent:" + percent);
  7. tripleValue(percent);
  8. System.out.println("After percent:" + percent);
  9.  
  10. System.out.println("---测试2 tripleSalary---");
  11. Employee harry =new Employee("Harry", 5000, 1);
  12. System.out.println("Before salary:" + harry.getSalary());
  13. tripleSalary(harry);
  14. System.out.println("After salary:" + harry.getSalary());
  15.  
  16. System.out.println("---测试3 swap---");
  17. Employee emp1 =new Employee("Alice", 1000, 1);
  18. Employee emp2 =new Employee("Bob", 1000, 1);
  19. System.out.println("Before emp1:" + emp1);
  20. System.out.println("Before emp2:" + emp2);
  21. swap(emp1, emp2);
  22. System.out.println("After emp1:" + emp1);
  23. System.out.println("After emp2:" + emp2);
  24.  
  25. }
  26.  
  27. public static void swap(Employee e1, Employee e2) {
  28. Employee tmp = e1;
  29. e1 = e2;
  30. e2 = tmp;
  31. }
  32.  
  33. public static void tripleSalary(Employee x) {
  34. x.setSalary(200);
  35. System.out.println("End of method salary:" +
  36. x.getSalary());
  37. }
  38.  
  39. public static void tripleValue(double x) {
  40. x *= 3;
  41. System.out.println("End of method x:" + x);
  42. }
  43.  
  44. }

  

  Employee实体类:

  1. public class Employee {
  2. private String name;
  3. private double salary;
  4. private int id;
  5.  
  6. public Employee(String name, double salary, int id) {
  7. this.name = name;
  8. this.salary = salary;
  9. this.id = id;
  10. }
  11.  
  12. public Employee() {
  13. }
  14.  
  15. public String getName() {
  16. return name;
  17. }
  18.  
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22.  
  23. public double getSalary() {
  24. return salary;
  25. }
  26.  
  27. public void setSalary(double byPercent) {
         double raise = this.salary * byPercent / 100;
  28. this.salary += raise;
  29. }
  30.  
  31. public int getId() {
  32. return id;
  33. }
  34.  
  35. public void setId(int id) {
  36. this.id = id;
  37. }
  38.  
  39. @Override
  40. public String toString() {
  41. return "Employee{" +
  42. "name='" + name + '\'' +
  43. ", salary=" + salary +
  44. ", id=" + id +
  45. '}';
  46. }
  47. }

  

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

  1. ---测试1 tripleValue---
  2. Before percent:10.0
  3. End of method x:30.0
  4. After percent:10.0
  5. ---测试2 tripleSalary---
  6. Before salary:5000.0
  7. End of method salary:15000.0
  8. After salary:15000.0
  9. ---测试3 swap---
  10. Before emp1:Employee{name='Alice', salary=1000.0, id=1}
  11. Before emp2:Employee{name='Bob', salary=1000.0, id=1}
  12. After emp1:Employee{name='Alice', salary=1000.0, id=1}
  13. 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节

Java语言对对象采用的是引用传递还是按值传递?的更多相关文章

  1. java 中对对象的调用

    java程序设计语言对对象采用的不是引用的调用,实际上对象引用进行的是值得传递.(from:核心卷1  page:123)

  2. java基本数据类型传递与引用传递区别

    文章转载自  zejian的博客http://blog.csdn.net/javazejian/article/details/51192130 java的值传递和引用传递在面试中一般都会都被涉及到, ...

  3. Java是值传递还是引用传递?

    Java的值传递和引用传递在面试中一般都会都被涉及到,今天我们就来聊聊这个问题.这个问题一般是相对函数而言的,也就是Java中所说的方法参数,那么我们先来回顾一下在程序设计语言中有关参数传递给方法的两 ...

  4. Java 值传递 or 引用传递?

    Java 方法传参 值传递 or 引用传递? 结论:Java采用的是值传递 先建立一些基础的概念 什么是值传递和引用传递? 值传递(pass by value):是指在调用函数时将实际参数复制一份传递 ...

  5. java是值传递还是引用传递

    首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...

  6. Java语言的9个主要特性

    Java作为时下很流行的一门编程语言,受到很多人的热爱,那么它有哪些特性呢?一起来看看吧. 1.Java语言是简单的 Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用.另 ...

  7. 【转】java方法参数传递方式--按值传递、引用传递

    java的方法参数传递方式有两种,按值传递和引用传递 1.按值传递 参数类型是int,long等基本数据类型(八大基本数据类型),参数传递的过程采用值拷贝的方式 代码片段1: public class ...

  8. Java值传递还是引用传递?

    回顾: 在程序设计语言中,将参数传递分为按值调用和按引用调用.按值调用:表示方法接收的是调用者提供的值.而按引用调用表示方法接收的是调用者提供的变量地址.一个方法可以修改传递引用所对应的变量值,而不能 ...

  9. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

随机推荐

  1. k8s部署使用Dashboard(十)

    安装Dashboard 前面博客Kubernetes 所有的操作我们都是通过命令行工具 kubectl 完成的.为了提供更丰富的用户体验,Kubernetes 还开发了一个基于 Web 的 Dashb ...

  2. java 泛型学习随笔

    对于java 泛型 编译时处理,运行时擦除的特点理解 对于编译时处理 在使用泛型相关的类或方法时,如果声明时的类型和具体使用时的类型不一致则直接会编译不通过 对于运行时擦除 当在运行时对两个相同类型但 ...

  3. 容器云平台No.9~kubernetes日志收集系统EFK

    EFK介绍 EFK,全称Elasticsearch Fluentd Kibana ,是kubernetes中比较常用的日志收集方案,也是官方比较推荐的方案. 通过EFK,可以把集群的所有日志收集到El ...

  4. B树【Balanced-Tree】

    一.引言 B树是二叉平衡树的一个变种,在学习之前,我们先了解一下二分法,二叉树的一些相关的基本概念,有助于我们更好的理解B树~ 二.二叉树 定义:二叉树即二叉平衡树 意义:通过二分法来进行元素查找,时 ...

  5. 一台电脑配置多个GigHub账号

    换了新的公司,原来的公司用SVN(比较老了),自己平时用码云(Gitee),新公司使用GitHub.前天通知我注册GitHub账号,但是并未通知用户名的事情(要求用自己的名字),原来的GitHub账号 ...

  6. tomcat在linux下安装

    1.下载地址: https://tomcat.apache.org/download-90.cgi 2.上传linux 3.查看是否上传成功 4.解压: 5.进入后,查看README.md文件,可以查 ...

  7. mysql-4-functions

    #进阶4:常见函数(单行函数) /* 将一组逻辑语句封装在方法体中,对外暴露方法名 语法: SELECT 函数名() [FROM 表名] 分类: 1.单行函数:concat,length,ifnull ...

  8. Lua 协同程序(coroutine)

    什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西. 协同是非常 ...

  9. 079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象

    079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象 本文知识点:实例化对象 说明:因为时间紧张,本人写博客过程中只是对知 ...

  10. windows10 热点一直显示正在断开中

    解决方法: Windows+x,打开"windows Powershell(管理员),执行以下命令:netsh winsock reset 重启电脑,就OK了