传递给java中方法的对象适用于原始副本

时间:2014-01-01 10:57:22

标签: java object reference biginteger

我有一个字段Sample,我正在做以下事情:

  1. 使用此类的对象作为参数调用方法。
  2. 对此对象进行一些操作。
  3. 原始对象毕竟发生了变化。
  4. 我与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
    

2 个答案:

答案 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对象,但两个变量(ab)都有引用同一个对象的值。通过一个变量进行的任何更改仍然可以通过另一个变量看到。 (有关详细信息,请参阅this Stack Overflow answer。)

答案 1 :(得分:3)

BigInteger是不可变的,每次都返回一个新对象。

您的Sample类是可变的,当您更改它时,它只有一个副本/值。