Java中能否利用函数参数来返回值
转自https://blog.csdn.net/da_da_xiong/article/details/70039532
我们在写代码时通常会遇到一种情况,就是我们可能希望在一个函数操作完成后返回两个值,这两个值互不关联并且不希望以数组的形式返回,甚至这两个返回值都不属于同一种类型,这种情况下在C或C++中可以轻易的使用一个引用的参数来将想要返回的值作为参数传入函数,等函数执行完毕后就可以得到你想要的“返回值”了。
但是这种情况在Java中可能就没有那么轻易了,我们知道Java语言最大的一项改变就是隐藏了类似C或C++中的指针操作,这给开发者带来了极大的好处,开始时不用在为调皮的指针头疼了,但是同样的,在某些场景下也会产生某些局限性,接下来我们来看看如果我们利用Java来完成C或C++中的通过函数来改变传入实参的值会出现哪些状况。
首先,我们先来试试最最基本的int型变量,看如下代码:
- package testCase;
- public class testCase {
- public static void main(String[] args) {
- int a = , b = ;
- System.out.println("Before swap: a is " + a + " b is " + b);
- swap(a, b);
- System.out.print("After swap: a is " + a + " b is " + b);
- }
- static void swap(int a, int b) {
- int tmp;
- tmp = a;
- a = b;
- b = tmp;
- }
- }
如上所示,这是一个最基本的交换值的操作,在C或C++中我们可以很简单的利用swap(int &a, int &b)来完成相关的操作,但是在Java中我们看看这个程序的运行结果如下:
我们不得不遗憾的发现类似于这样的基本类型想要通过函数参数来改变在Java中是不可能实现的,我们不禁想到,基本类型不行我们可以使用对象啊,对象在Java中确实传递的是地址,但是这个地址也有些微妙所在,我们看下面这个例子,仍然使用我们的神奇的交换函数,代码如下:
- package testCase;
- public class testCase {
- public static void main(String[] args) {
- StringBuffer a = new StringBuffer("hello a"), b = new StringBuffer("hello b");
- System.out.println("Before swap: a is " + a + " b is " + b);
- swap(a, b);
- System.out.print("After swap: a is " + a + " b is " + b);
- }
- static void swap(StringBuffer a, StringBuffer b) {
- StringBuffer tmp;
- tmp = a;
- a = b;
- b = tmp;
- }
- }
这个程序的运行结果是怎样的呢?结果如下所示:
这是为什么呢?我们要理解一个概念,那就是我们传地址实际上也是值传递,我们把实参存储的地址通过拷贝给了形参,在函数中传递参数后(还未做交换操作时)实参a与形参a的指向情况如下:
如上图所示,在传入参数时实参a将其存储的地址(@32,我们假设这个值是字符串”hello a”的地址)拷贝给了形参a,这时这两个对象均指向”hello a”。
之后我们进行交换操作,交换操作完成后的指向如下所示:
此时我们发现我们仅仅是将形参的指向改变了,根本未能交换两个实参的指向,oh,no,到头来一场空。
我们试试下面的用法,具体程序如下:
- package testCase;
- public class testCase {
- public static void main(String[] args) {
- StringBuffer a = new StringBuffer("hello a");
- System.out.println("Before change: a is " + a);
- change(a);
- System.out.print("After change: a is " + a);
- }
- static void change(StringBuffer a) {
- a.append(" hello world");
- }
- }
这里我们通过形参来改变实参指向的内容的值试试,运行结果如下:
嘿嘿,是不是还有点用,说到这里我们就明白了吧,我们改变指向是没用的,但我们去改变指向的内容的值是会生效的。
接下来我们不禁想到我们是不是可以用基础类型的封装类型来操作一波,封装类型是对象啊,这是毋庸置疑的,我们来看如下代码:
- package testCase;
- public class testCase {
- public static void main(String[] args) {
- Integer a = Integer.valueOf();
- System.out.println("Before change: a is " + a);
- change(a);
- System.out.print("After change: a is " + a);
- }
- static void change(Integer a) {
- a = Integer.valueOf();
- }
- }
来看看运行结果吧,如下所示:
是不是一脸懵逼,百思不得其解,接下来我们看看Integer的源码吧,代码如下:
- public static Integer valueOf(int i) {
- assert IntegerCache.high >= ;
- if (i >= IntegerCache.low && i <= IntegerCache.high)
- return IntegerCache.cache[i + (-IntegerCache.low)];
- return new Integer(i);
- }
继续往下看,Integer(int i)的定义如下:
- public Integer(int value) {
- this.value = value;
- }
这个value是怎么定义的呢,我们看看,value定义如下:
- /**
- * The value of the {@code Integer}.
- *
- * @serial
- */
- private final int value;
明白了吧,这个value它是个final类型的,简直坑爹,类似的封装类型(基本类型的封装类)都是这种调调,完全用不鸟,我们关于对象的举例为什么用了StringBuffer而不用String呢?因为String类型也是不会生效的,具体原因是为什么呢?我们就不再追代码了,实际上String虽然是一个对象类型,但其实它也是对char[]的封装,所以它也可以看作一个封装类型,因此,它也是不会生效的。
好了,关于Java能否做到类似C语言改变传入实参的值的分析就到这里了,经过上述的分析,我们大致了解了其实对于Java来说这个用法其实并不怎么好用,还不如定义一个自己的数据类型来返回来的自由愉快,希望大家能够从我的这篇博客中学到新的知识,欢迎大家留言一起讨论。
Java中能否利用函数参数来返回值的更多相关文章
- 058、Java中定义一个没有参数没有返回值的方法
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 059、Java中定义一个有参数无返回值的方法
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- python函数进阶(函数参数、返回值、递归函数)
函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...
- JAVA中执行JavaScript代码并获取返回值
JAVA中执行JavaScript代码并获取返回值 场景描述 实现思路 技术要点 代码实现 测试方法 运行结果 改进空间 场景描述 今天在CSDN上偶然看到一个帖子对于一段字符串 “var p=‘xx ...
- Python基础之函数参数与返回值进阶
参数作用:如果外界希望在函数内部处理数据,就可以将数据作为参数传入函数内部: 返回值作用:如果希望一个函数函数执行完成后,向外界报告函数的执行结果,就可以使用函数的返回值. 函数的返回值 进阶 利用元 ...
- JS基础语法---函数---介绍、定义、函数参数、返回值
函数: 把一坨重复的代码封装,在需要的时候直接调用即可 函数的作用: 代码的重用 函数需要先定义,然后才能使用 函数名字:要遵循驼峰命名法 函数一旦重名,后面的会把前面的函数覆盖 Ctrl +鼠标左键 ...
- javascript函数参数、返回值类型检查
实现带参数.返回值类型声明的js函数: 类型定义:window.Str = Type.Str = Type.define('STRING', Type.isStr);var Per = Type.de ...
- 04 python学习笔记-函数、函数参数和返回值(四)
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.Python提供了许多内建函数,比如print(),我们也可以自己创建函数,这叫做用户自定 ...
- c++函数参数或返回值为函数指针
C++中函数指针的形式为:返回值类型 + 参数类型,函数没有值类型,但是却可以声明函数的指针,因为函数是可寻址的,存放在内存中的代码段,可以从指针访问. 函数指针可以声明为: void (*pF)(v ...
随机推荐
- FCL源码中数组类型的学习及排序函数Sort函数的分析
Array 是所有数组的基类ArrayList 解决了所有Array 类的缺点 能动态扩容, 但是类型不安全的,而是会有装箱与拆箱的性能开销List<T> 则是解决了ArrayLis ...
- JVM学习--(七)性能监控工具
前言 工欲善其事必先利其器,性能优化和故障排查在我们大都数人眼里是件比较棘手的事情,一是需要具备一定的原理知识作为基础,二是需要掌握排查问题和解决问题的流程.方法.本文就将介绍利用性能监控工具,帮助开 ...
- iOS中用UILabel实现UITextView的占位文字
@interface BSPublishTextView : UITextView /** 对外属性占位字符 placeholder */ @property (nonatomic, copy) NS ...
- plsql使用
本文由jay8605162432贡献 本课重点: 1.写 SELECT 语句进行数据库查询 2.进行数学运算 3.处理空值 4.使用别名 ALIASES 5.连接列 6.在 SQL PLUS 中编辑缓 ...
- [C#网络应用编程]2、对线程的管理
在System.Threading命名空间下,有一个Thread类,用于对线程进行管理,如创建线程.启动线程.终止线程.合并线程.让线程休眠等 Thread类 (假设Thread firTh = ne ...
- jsoup 使用总结1--添加header
jsoup 使用总结1--添加header 大部分时候,我们使用jsoup解析网页的是否都是直接Jsoup.connect(url); 孰不知,我们可以添加header,例如 Host, Refere ...
- 畅通工程-HZNU寒假集训
畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只 ...
- Hive入门学习--HIve简介
现在想要应聘大数据分析或者数据挖掘岗位,很多都需要会使用Hive,Mapreduce,Hadoop等这些大数据分析技术.为了充实自己就先从简单的Hive开始吧.接下来的几篇文章是记录我如何入门学习Hi ...
- php中$_FILES应用实例
允许用户从表单上传文件是非常有用的.先来看一段HTML表单代码 <html> <body> <form action="upload_file.php" ...
- Hibernate二级缓存简述及基于Spring4,Hibernate5,Ehcache3的二级缓存配置
Hibernate L2缓存 缓存的分类 L2缓存工作原理 放入二级缓存的数据 Ehcache 依赖 ehcache.xml 常用的memoryStoreEvictionPolicy(缓存算法) eh ...