java函数输出参数_Java中能否利⽤函数参数来返回值
我们在写代码时通常会遇到⼀种情况,就是我们可能希望在⼀个函数操作完成后返回两个值,这两个值互不关联并且不希望以数组的形式返回,甚⾄这两个返回值都不属于同⼀种类型,这种情况下在C或C++中可以轻易的使⽤⼀个引⽤的参数来将想要返回的值作为参数传⼊函数,等函数执⾏完毕后就可以得到你想要的“返回值”了。
但是这种情况在Java中可能就没有那么轻易了,我们知道Java语⾔最⼤的⼀项改变就是隐藏了类似C或C++中的指针操作,这给开发者带来了极⼤的好处,开始时不⽤在为调⽪的指针头疼了,但是同样的,在某些场景下也会产⽣某些局限性,接下来我们来看看如果我们利⽤Java 来完成C或C++中的通过函数来改变传⼊实参的值会出现哪些状况。
⾸先,我们先来试试最最基本的int型变量,看如下代码:
package testCase;public classtestCase {public static voidmain(String[] args) {int a = 0, b = 1;
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, intb) {inttmp;
tmp=a;
a=b;
b=tmp;
}
}
如上所⽰,这是⼀个最基本的交换值的操作,在C或C++中我们可以很简单的利⽤swap(int &a, int &b)来完成相关的操作,但是在Java中我们看看这个程序的运⾏结果如下:
我们不得不遗憾的发现类似于这样的基本类型想要通过函数参数来改变在Java中是不可能实现的,我们不禁想到,基本类型不⾏我们可以使⽤对象啊,对象在Java中确实传递的是地址,但是这个地址也有些微妙所在,我们看下⾯这个例⼦,仍然使⽤我们的神奇的交换函数,代码如下:
package testCase;public classtestCase {public static voidmain(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 voidswap(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 classtestCase {public static voidmain(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 voidchange(StringBuffer a) {
a.append("hello world");
}
}
这⾥我们通过形参来改变实参指向的内容的值试试,运⾏结果如下:
嘿嘿,是不是还有点⽤,说到这⾥我们就明⽩了吧,我们改变指向是没⽤的,但我们去改变指向的内容的值是会⽣效的。
java valueof接下来我们不禁想到我们是不是可以⽤基础类型的封装类型来操作⼀波,封装类型是对象啊,这是⽏庸置疑的,我们来看如下代码:
package testCase;public classtestCase {public static voidmain(String[] args) {
Integer a= Integer.valueOf(0);
System.out.println("Before change: a is" +a);
change(a);
System.out.print("After change: a is" +a);
}static voidchange(Integer a) {
a= Integer.valueOf(1);
}
}
来看看运⾏结果吧,如下所⽰:
是不是⼀脸懵逼,百思不得其解,接下来我们看看Integer的源码吧,代码如下:
public static Integer valueOf(inti) {
assert IntegerCache.high>= 127;if (i >= IntegerCache.low && i <=IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return newInteger(i);
}
继续往下看,Integer(int i)的定义如下:
public Integer(intvalue) {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来说这个⽤法其实并不怎么好⽤,还不如定义⼀个⾃⼰的数据类型来返回来的⾃由愉快,希望⼤家能够从我的这篇博客中学到新的知识,欢迎⼤家留⾔⼀起讨论。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论