Java错误记录:将Integer类型参数传递给方法

问题来源:

在使用Java做某个实验的时候,有一个方法需要传入一个整数类型的值并在方法内修改值的大小。1
显然,使用int是不可行的,于是本着“只要传入引用类型就可以在方法内修改它的值”的误区,使用了Integer类型。图:修改Integer类型的值失败
但事实上执行上述changeInteger()方法后的,integer的值还是1。
IDEA也给出了警告,在方法内修改后的是never used的。

原因

在Integer类型的源码中,我找到了如下一段:
图:Integer类型源码可以看到Integer类型的值是被final修饰了的,也就是说一旦创建就不能改变。
我们再做一个测试,该测试返回一个Integer类型的引用每次改变后的哈希值:

class Values{
    static void changeInteger(Integer aInteger){
        System.out.println("a传给方法中的aInteger后:" + System.identityHashCode(aInteger));
        aInteger += 1;
        System.out.println("aInteger在方法内改变后:" + System.identityHashCode(aInteger));
    }
}

public class AboutInteger {
    public static void main(String[] args){
        Integer a = 0;
        System.out.println("a改变前:" + System.identityHashCode(a));
        Values.changeInteger(a);
        System.out.println("a传入方法后:" + System.identityHashCode(a));
        a = 3;
        System.out.println("a第一次改变后:" + System.identityHashCode(a));

    }
}

结果为:
a改变前:793589513
a传给方法中的aInteger后:793589513
aInteger在方法内改变后:1349393271
a传入方法后:793589513
a第一次改变后:1338668845

可以看到a传给方法后,相当于是a和aInteger都引用了哈希值为793589513的这个对象,但是一旦a或者aInteger被改变后,它们所引用的对象就与原来不同了。所以在方法中改变了aInteger,相当于是在方法中把aInteger重新指向了一个新的对象,当然不能改变原来的a值了。

再看一段源码:
图:Integer类型源码2
首先,给Integer类型赋值相当于执行了:a = Integer.valueof(int i),而在源码中,可以看到如果i在常量池范围内(一般是-128到127),就会从常量池中获取一个Integer对象,如果不在范围内,就会new一个对象。不管是哪种情况,都不再是原来所引用的对象了。

总结

改变Integer类型的值,不是像一般的引用类型一样执行一个Object.value = 1,因为在Integer中value被final修饰,不能改变。事实上是执行了Integer.valueof(int i)方法,该方法无论如何都会创建一个新的对象。

解决方案

  1. 使用返回值将必须在方法中修改的Integer类型返回
  2. 封装一个类myInteger{Integer value;}

参考文章:
【1】 以Integer类型传参值不变来理解Java值传参
【2】 工作中Integer类型传参遇到的陷阱
【3】 Integer参数传递问题


  1. 文章内容部分参考网络。主要作为自己整理的笔记使用。理解上表达上可能存在错误,欢迎指正。 ↩︎

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值