资讯专栏INFORMATION COLUMN

Java方法参数

ASCH / 1584人阅读

摘要:方法结束后,参数不再使用了,但是仍然指向那个已经被提高了工资的对象。总结中方法参数的使用情况一个方法不能修改一个基本数据类型的参数。一个方法可以改变一个对象参数的状态。

最近在看《java核心技术卷1》,看到4.5章节的时候解决了以前一直有些疑惑的问题。

记录如下:

首先,在程序设计语言中,将参数传递给方法(或函数)的术语有:

按值调用(call by value)表示方法接收的是调用者提供的值。
按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。
书中还提到了Algol的按名称调用。

在java中:
java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。

例如,考虑代码:

double percent = 10;
harry.raiseSalary(persent);

暂且不用管这段代码的具体实现,书中这个章节用了雇员类来解释很多事情,我们现在只要知道这种调用的方式并不能让percent的值进行改变就可以了。

以上是一个简单的例子,说明了java参数传递的方式。下面将从参数为基本数据类型和对象引用两种情况进行分析:

方法参数为基本数据类型:
public static void tripleValue(double x)
{
       x = 3 * x;
}

然后调用:

double percent = 10.0;
tripleValue(percent);

调用之后,percent的值还是10.0,并没有什么变化。
下面看一下具体的执行的过程:
1.x被初始化为percent值的一个拷贝,也还是10。
2.x被乘以了3,然后x变成了30,但是percent仍然是10,因为毕竟是对x的操作,并没有改变percent。
3.方法结束之后,x被弃用了,结果percent还是10。

方法参数为对象引用类型:

(Employee为章节中的一个例子的类,这个类中有raiseSalary方法,这个方法的参数是提高工资的百分比。构造函数也不是重点所以参数就用...代替了,不便之处还请谅解)

public static void tripleSalary(Employee x)
{
        x.raiseSalary(200);
}

当调用:

harry = new Employee(...);
tripleSalary(harry);

具体的执行过程为:
1.x被初始化为harry值的拷贝,这里是一个对象的引用。
2.raiseSalary方法应用于这个对象的引用,x和harry同时引用的那个Employee对象的薪资提高了200%。
3.方法结束后,参数x不再使用了,但是harry仍然指向那个已经被提高了200%工资的对象。

所以经过以上的例子,有些人可能认为java是按引用调用的,实际上这种理解是不对的。下面举出一个反例:
编写一个交换两个雇员对象的方法:

public static void swap(Employee x, Employee y)
{
        Employee temp = x;
        x = y;
        y = temp;
}

如果是按引用调用的那么应该可以实现对换数据的效果:

Employee a = new Employee("Alice"...);
Employee b = new Employee("Bob"...);
swap(a,b);

但是,并没有改变存储在变量a和b中的对象引用,swap方法其实交换的是方法中的xy的引用,也就是a和b的拷贝。对于方法外的ab是没有影响的。

这个过程说明了java对对象采用的也不是按引用调用,也是按值调用的。

总结java中方法参数的使用情况:

1.一个方法不能修改一个基本数据类型的参数。
2.一个方法可以改变一个对象参数的状态。(比如修改这个对象中的某个属性值)
3.一个方法不能让对象参数引用一个新的对象。(这句话我的理解是不管你在函数中怎么折腾传进来的那个对象的引用,函数结束了之后对外面都没什么效果,当然了,如果修改了引用对象内的属性,那就属于情况2的情况了。这句话是对交换的例子的总结)

总之

java是按照传值调用的,而不是引用,希望以上的例子和解释能给新手或者对这部分不太清楚的同学们些帮助,如果有不恰当的地方,还请指教。
谢了!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64462.html

相关文章

  • Java™ 教程(类型推断)

    类型推断 类型推断是Java编译器查看每个方法调用和相应声明的能力,以确定使调用适用的类型参数,推理算法确定参数的类型,如果可用,还确定分配或返回结果的类型,最后,推理算法尝试查找适用于所有参数的最具体类型。 为了说明最后一点,在下面的示例中,推断确定传递给pick方法的第二个参数是Serializable类型: static T pick(T a1, T a2) { return a2; } ...

    JerryC 评论0 收藏0
  • Java 8怎么了:局部套用vs闭包

    摘要:本文主要介绍了中的闭包与局部套用功能,由国内管理平台编译呈现。譬如,认为给带来了闭包特性就是其中之一。但是首先,我们将考虑如何利用闭包进行实现。很显然,闭包打破了这一准则。这就是局部调用,它总是比闭包更为稳妥。 【编者按】本文作者为专注于自然语言处理多年的 Pierre-Yves Saumont,Pierre-Yves 著有30多本主讲 Java 软件开发的书籍,自2008开始供职于 ...

    3fuyu 评论0 收藏0
  • 乐字节-Java8新特性之函数式接口

    摘要:上一篇小乐带大家学过新特性表达式,什么时候可以使用通常表达式是用在函数式接口上使用的。使用实现创建产生一个工厂对象以上就是小乐带给大家的新特性之函数式接口,下一篇将会为大家带来新特性之方法引用,敬请关注。 上一篇小乐带大家学过 Java8新特性-Lambda表达式,什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的。从Java8开始引入了函数式接口,其说明比较...

    lakeside 评论0 收藏0
  • 为何Spring MVC可获取到方法参数名,而MyBatis却不行?【享学Spring MVC】

    每篇一句 胡适:多谈些问题,少聊些主义 前言 Spring MVC和MyBatis作为当下最为流行的两个框架,大家平时开发中都在用。如果你往深了一步去思考,你应该会有这样的疑问: 在使用Spring MVC的时候,你即使不使用注解,只要参数名和请求参数的key对应上了,就能自动完成数值的封装 在使用MyBatis(接口模式)时,接口方法向xml里的SQL语句传参时,必须(当然不是100%的必须,...

    孙淑建 评论0 收藏0
  • 乐字节-Java8核心特性实战之函数式接口

    摘要:大家好,上一篇小乐给大家讲述了乐字节核心特性表达式,点击回顾。接下来继续核心特性之函数式接口。感谢大家欣赏小乐带来的核心特性之函数式接口,接下来还会更多核心技术讲解,请关注乐字节如需要视频课程,请搜索乐字节腾讯课堂 大家好,上一篇小乐给大家讲述了《乐字节-Java8核心特性-Lambda表达式》,点击回顾。接下来继续:Java8核心特性之函数式接口。 什么时候可以使用Lambda?通常...

    niceforbear 评论0 收藏0
  • Java 运行时获取方法参数

    摘要:原文如果觉得我的文章对你有用,请随意赞赏本文整理运行时获取方法参数名的两种方法,的最新的方法和之前的方法。文件中的调试信息上文介绍了通过新增的反射运行时获取方法参数名。 原文:http://nullwy.me/2017/04/java...如果觉得我的文章对你有用,请随意赞赏 本文整理 Java 运行时获取方法参数名的两种方法,Java 8 的最新的方法和 Java 8 之前的方法。 ...

    cfanr 评论0 收藏0

发表评论

0条评论

ASCH

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<