java编程中容易犯错的地方之BigInteger
?
在java中,有很多容易被忽视的地方,今天在网上看到一个java的谜题,代码如下:
?
?
BigInteger five = new BigInteger("5");BigInteger four = new BigInteger("4");BigInteger total = BigInteger.ZERO;total.add(five);total.add(four); System.out.println(total);
?
乍一看,觉得这个代码应该输出9,毕竟4+5=9嘛。其实,如果你运行一下这段代码(这段代码不能直接运行,你得需要修改一下),会惊奇的发现,这段代码居然打印出了0。
?
分析:
- 不可变类型种类:String、BigDecimal、BigInteger和各种包装器类型都是不可变类型。对于String不可变的特性在我另一篇博文中说到。比如BigInteger的add方法,并不会改变两个操作数即现有实例,而是返回新的实例。
?
结论:
在调用不可变对象的方法时,如果对于看起来是对对象进行改变的方法,则现有实例并不会改变,而是返回一个新的实例。
1 楼 zhushaolong 2012-09-04 就像String是不可变的 2 楼 web001 2012-09-04 zhushaolong 写道就像String是不可变的对啊,是不可变的。 3 楼 kimmking 2012-09-04 scala中的val和var 4 楼 web001 2012-09-04 kimmking 写道scala中的val和var
求详细解释? 5 楼 tlde_ti 2012-09-04 web001 写道kimmking 写道scala中的val和var
求详细解释?
不太一样,val var 是 变量的指向可变与不可变。而这里是object的可变与不可变。
val 相当于 final. 6 楼 ray_linn 2012-09-04 真丑陋... 7 楼 HeartArea 2012-09-04 说白了 就是这些类型的方法调用结束以后 你得用变量接收一下,否则运算无效 8 楼 tlde_ti 2012-09-04 tlde_ti 写道web001 写道kimmking 写道scala中的val和var
求详细解释?
不太一样,val var 是 变量的指向可变与不可变。而这里是object的可变与不可变。
val 相当于 final.
题外话,让我想到了 java一直在讨论的值传递还是引用传递问题,其实那个讨论忽略了一个前提,mutable object并不是值,因为它不符合 值 不可更改 的定义。
immutable object 和 primitive type 倒是符合值的定义,从抽象上来说,不管 值 传 的是 值的复制还是值,其实都是一个东西,因为所有相等的值抽象上都是一样的。你不用考虑任何区别。thinking in java 的值的复制的说法 完全是无谓增加复杂度。
然后就只需要考虑mutable object的传递,首先我们不应该考虑底层这里是怎么实现的,这只会把人的脑子缴晕。我们只需要考虑展示给我们看的抽象概念就可以了。
第一点,传递的肯定不是 变量,因你将变量的引用改变并不会改变原变量的 指向。
第二点,传递的是变量的复制,还是mutable object呢?thinking in java 说是 reference的复制,我觉得是多此一举。因为reference的复制意义就是现在的变量和原来的变量不是一个东西!!
这里完全可以简单的理解为 是直接将 mutable object 传了过来 然后我们给予他一个新的变量。
结论就是:如果传的是 值,那传的就是值,传的是mutable object,传的就是mutable object,只是给了个新变量。 多好理解啊...thinking in java害人不浅.最近还放话说要写
atomic scala 继续祸害 java转到 scala的人们 - - 9 楼 解未知数 2012-09-04 我觉得 BigInteger total = BigInteger.ZERO; 这种写法, 是不好的习惯.
total.add 其实操作的是BigInteger的静态ZERO变量.
幸好BigInteger是不可改变的, 要不然麻烦就大了.
最好还是写成 BigInteger total = new BigInteger("0");