Java包装类作为参数传递
Java包装类作为参数传递
今天在回顾Java基础的时候发现了这么⼏⾏代码:
public static void passReferenceValue(Boolean flg, Integer num) {
flg = true;
num = 10;
}
public static void main(String[] args) {
Boolean a = false;
Integer b = 5;
System.out.println("a : " + a + " b : " + b);
passReferenceValue(a, b);
System.out.println("a : " + a + " b : " + b);
}
猜测结果:
a : false
b : 5
a : true
b : 10
实际结果:
a : false
b : 5
a : false
b : 5
我认为在java中包装类被传⼊⽅法中是引⽤传递,所以在⽅法中对包装类的值进⾏修改后其会改变,但是实际上的结果却和基本类型值传递是⼀样的效果。
我们都知道,上述⽅法中的修改过程涉及到了⾃动装箱和拆箱:
⾃动装箱就是Java⾃动将原始类型值转换成对应的包装类型,如将int的变量转换成Integer对象,这个过程叫做装箱。反之将Integer 引⽤类型转换成int类型值,这个过程叫做拆箱。因为装箱和拆箱是⾃动进⾏的⾮⼈为转换,所以就称作为⾃动装箱和拆箱。
基本数据类型:byte,short,char,int,long,float,double、boolean
对应的封装类为:Byte,Short,Character,Integer,Long,Float,Double,Boolean
⾃动装箱时编译器调⽤valueOf将基本类型值转换成引⽤类型。
⾃动拆箱时,编译器通过调⽤类似intValue(),doubleValue()这类的⽅法将对象转换成原始类型值。
所以来到Integer包装类的源码,我们很快定位到valueOf()⽅法:
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
上述的parseInt()⽅法为 public static int parseInt(String s, int radix) throws NumberFormatException,很明显其返回了int数值。
然后我们定位到return后的Interger.valueOf()⽅法:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
最终发现是Interger.valueOf()返回了⼀个new出来的对象 —— 新Integer造成了
num = 10;
成为了
num = new Integer(...);
⽅法中改变引⽤对象的地址后是不会改变原有对象所指向的地址的。
到这⾥,我想⼤家已经明⽩了包装类作为参数传递在⽅法中修改为什么其值没有被修改,这是因为在⾃动装箱和拆箱的过程中原来的赋值被替换为了新的对象。
那么有的⼩伙伴可能想问,那么Boolean呢。
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
这个TRUE不是我们迫使所认为的true,⽽是指:java valueof
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code true}.
*/
public static final Boolean TRUE = new Boolean(true);
...
没错,这个TRUE是⼀个Boolean对象,FALSE也是⼀样,这就是为什么⼀开始的代码中⽅法对传⼊包装类赋值失败的原因。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。