我有一个字段Sample
,我正在做以下事情:
我与BigInteger
类对象做同样的事情,它的工作方式不同。为什么会这样?
我的课程:
public class Sample {
private int number;
public int getNumber(){
return number;
}
public void setNumber(int number){
this.number = number;
}
public Sample add(int number){
this.number += number;
return this;
}
}
调用:
public class Main {
public static void main(String[] args) {
Main m = new Main();
BigInteger b1 = new BigInteger("5");
Sample s1 = new Sample();
s1.setNumber(3);
System.out.println(s1.getNumber());
Sample s2 = m.checkSample(s1);
BigInteger b2 = m.checkBig(b1);
System.out.println(s1.getNumber()+" "+s2.getNumber());
System.out.println(b1.toString()+" "+b2.toString());
}
public Sample checkSample(Sample k){
k = k.add(5);
return k;
}
public BigInteger checkBig(BigInteger big){
big = big.add(new BigInteger("2"));
return big;
}
}
输出:
3
8 8
5 7
答案 0 :(得分:5)
您在使用BigInteger
时没有做同样的事情 - 您正在调用add
方法,该方法返回对 new BigInteger
的引用,以及您将该值分配回big
。
您的Sample.add
方法会更改现有对象:
public Sample add(int number){
this.number += number;
return this;
}
如果您更改它以返回对新对象的引用,它将表现得像BigInteger
:
public Sample add(int number){
Sample sample = new Sample();
sample.setNumber(sample.number + number);
return sample;
}
但是,与Sample
不同,您的BigInteger
课程目前基本上是可变的。 BigInteger
上的任何操作都不会更改现有对象的状态;相反,他们所有创建新对象。如果您想在Sample
中复制该行为,您可以这样写:
public final class Sample {
private final int number;
public Sample(int number) {
this.number = number;
}
public int getNumber(){
return number;
}
public Sample add(int number){
return new Sample(this.number + number);
}
}
重要的是要了解您永远不会在Java中传递对象 - 仅用于导航到对象的引用。例如:
StringBuilder a = new StringBuilder();
StringBuilder b = a;
b.append("hello");
System.out.println(a); // Prints hello
这里有一个单个 StringBuilder
对象,但两个变量(a
和b
)都有引用同一个对象的值。通过一个变量进行的任何更改仍然可以通过另一个变量看到。 (有关详细信息,请参阅this Stack Overflow answer。)
答案 1 :(得分:3)
BigInteger是不可变的,每次都返回一个新对象。
您的Sample类是可变的,当您更改它时,它只有一个副本/值。