程序设计语言中将参数传递给方法的几种方式:

  1. 按名调用(call by name): Algol 语言采用此方式, 已成为历史;
  2. 按值调用(call by value): 方法接收到的是调用者提供的 变量值;
  3. 按引用调用(call by reference): 方法接受到的是调用者低筒的 变量地址;

C++ 支持 按值调用按引用调用:

void func(int arg); // 按值调用;
void func(int& arg); // 按引用调用;

而 java 只支持 按值调用, 也就是说方法得到的是所有参数值的一个拷贝, 在方法内对参数值进行修改是不会影响原值的.

然而方法参数有两种类型:

  1. 基本数据类型: 数字, 布尔值;
  2. 对象引用.

当方法参数是 对象引用 时, 在方法很容易的调用其 setXXX 方法修改该对象属性值, 在退出方法后该修改仍然有效, 但这仍旧只是 按值调用.

因为参数是 对象引用, 在该方法内仍旧执行原对象(类似 C++ 的指针), 调用它的 setXXX 方法当然能修改对象属性了. 但也仅限于修改对象属性(状态), 而不能通过 new 等方式对原对象进行修改.

如果还有疑问, 就请看看这个例子:

class MyObject {
private String name;
MyObject(String name) {
this.name = name;
}
} static void swap(MyObject first, MyObject second) {
MyObject temp = first;
first = second;
second = first;
} static void testSwap() {
MyObject a = new MyObject("a");
MyObject b = new MyObject("b"); swap(a, b);
}

请问在执行 swap() 函数后, 对象 a 和 对象 b 的 name 是否变化?

答案是没有变化. 在 testSwap() 方法中, firstsecond 完成交换并分别指向对方. 但是, 在进入方法时, 它们拿到的是对象引用的拷贝(位置), 类似于:

  • 进入 swap() 方法前, a 知道在内存地址为 100 的地方存储了一个 MyObject 对象, 'b' 知道在内存地址为 200 的地方存储了另一个 MyObject 对象;
  • 进入 swap() 方法时, a 将它的对象引用复制一份给 first, 也就是说 first 知道内存地址为 100 的地方有一个 MyObject 对象. second 同理;
  • 在退出 swap() 方法时, firstsecond 交换值, 也就是说 first 知道内存地址为 200 的地方有一个 MyObject 对象, 它已经跟内存地址为 100 的 MyObject 对象没有任何关系了. second 同理;
  • 在退出 swap() 方法后, firstsecond 被销毁, a 仍旧是知道内存地址为 100 的地方有一个 MyObject 对象...

其实, 这就是 C/C++ 的指针.

顺便说一句, 通过 C++ 的 按引用调用 可以很方便实现 swap() 函数. 当然, 用指针也是支持滴, 只不过稍微复杂点(这里只给出声明, 有兴趣的同学自己去写实现吧):

MyObject* a = new MyObject("a");
MyObject* b = new MyObject("b"); void swap(MyObject& first, MyObject& second); // C++ 引用 void swap(MyObject **first, MyObject **second); // C/C++ 指针版 swap

综上, java 中的方法参数:

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

java 方法传参方式: 按值调用的更多相关文章

  1. 再谈Java方法传参那些事

    把一个变量带进一个方法,该方法执行结束后,它的值有时会改变,有时不会改变.一开始会觉得--“好神奇呀”.当我们了解java内存分析的知识后,一切都是那么简单明了了--“哦,这么回事呀”.但是今天的上机 ...

  2. java 线程传参 方式

    第一类:主动向线程传参   public class ThreadTest extends Thread { public ThreadTest() { } /** * 第一种通过构造方法来传递参数 ...

  3. Java Mybatis 传参方式

    一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...

  4. Java方法传参,测试在方法内部改变参数内容是否会影响到原值

    我分了三种类型的参数进行测试 一.基本类型 public static void main(String[] args) { System.out.println("验证基本类型int作为参 ...

  5. Java方法传参的问题

    1.基本数据类型(byte,short,int,long,float,double,boolean,char)的值传递,不改变其值 2.引用数据类型的值传递,改变其值 3.String类型虽然是引用数 ...

  6. 浅谈对java中传参问题的理解

    之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...

  7. java 传参方式--值传递还是引用传递

    java 传参方式--值传递还是引用传递 参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递.写它是为了揭穿普遍存在的一种神话,即认为 Java 应用程序按引用 ...

  8. Java 常用类库一,main方法传参String[] args;获取输入Scanner ;hasNext();hasNextInt()

    1. main方法传参 package com.zmd.common_class_libraries; /** 给mian方法传参测试 */ public class MainArgsTest { p ...

  9. java的方法传参,最容易混淆的问题!!!

    参数传递 参数传递,可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了.这种传递方式,我们称为参数传递. 在这里 ...

随机推荐

  1. python3生成测试数据,并写入ssdb

    import pyssdb import random import time c = pyssdb.Client() chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoP ...

  2. Docker背后的内核知识:命名空间资源隔离---亲测

    参考URL: https://linux.cn/article-5057-1.html 实现代码(网络和用户空间只是看懂了) 实际上,Linux内核实现namespace的主要目的就是为了实现轻量级虚 ...

  3. [BZOJ1076][SCOI2008]奖励关 状压dp

    1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3070  Solved: 1595[Submit][Statu ...

  4. 【cocos2d-js官方文档】十一、cc.path

    概述 该单例是为了方便开发者操作文件路径所设计的.定义为cc.path的目的是为了跟nodejs的path保持一致.里面定义的api也基本跟nodejs的path模块一致,但不全有,今后可能还会继续根 ...

  5. Square Number & Cube Number

    Square Number: Description In mathematics, a square number is an integer that is the square of an in ...

  6. win7 office2016 激活(2018.6.17测试可用)

    坑比的一天,啥也没学,净用来折腾了office2016的安装了. 虽然有个wps可以用,但是真心的卡啊,用不惯就卸载了.虽然是卸载了,也埋了很多坑给我. 还是说office2016吧,网上到处找激活工 ...

  7. Codeforces 920 G List Of Integers

    题目描述 Let's denote as L(x,p)L(x,p) an infinite sequence of integers yy such that gcd(p,y)=1gcd(p,y)=1 ...

  8. iOS 修改APP工程名字

    我们在iOS开发中,难免会遇到项目做到一半要改名字的情况.如果项目名差的太大,工程名看起来总是不舒服的,就会想着为工程改个贴切的名字,那么你就为用到本文记录的内容. 如何修改工程名呢? 下面我就拿一个 ...

  9. C#测试程序运行时间

    一.用C#自带的StopWatch函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System; usi ...

  10. 关于DNS,你应该知道这些

    在互联网时代中,如果要问哪个应用层协议最重要的话,我想答案无疑是DNS.虽然我们每天都享受着DNS服务带来的便利, 却对它往往知之甚少.因此本文就来介绍一下DNS协议的工作流程,真正认识一下这个支撑着 ...