簡體   English   中英

傳遞給Java中方法的對象在原始副本上有效

[英]Object passed to method in java works on original copy

我有一個字段的Sample類,並且正在做以下事情:

  1. 以此類的對象作為參數的調用方法。
  2. 對這個對象進行一些操作。
  3. 原始對象畢竟變了。

我在用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

您沒有使用BigInteger做同樣的事情-您正在調用add方法,該方法返回對 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;
}

但是,與BigInteger不同,此刻您的Sample類目前基本上是可變的。 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 )具有指向同一個對象的值。 通過一個變量進行的任何更改仍然可以通過另一個變量看到。 (有關更多信息,請參見此堆棧溢出答案 。)

BigInteger是不可變的,每次都返回一個新對象。

您的Sample類是可變的,當您對其進行更改時,它僅保留一個副本/值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM