簡體   English   中英

如何從另一種方法增加java中的類整數引用值

[英]How to Increment a class Integer references value in java from another method

package myintergertest;

/**
 *
 * @author Engineering
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //this one does not increment 
        Integer n = new Integer(0);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);

        //this one will increment
        MyIntegerObj myInt = new MyIntegerObj(1);
        Increment(myInt);
        System.out.println("myint = " + myInt.get());
        Increment(myInt);
        System.out.println("myint = " + myInt.get());
        Increment(myInt);
        System.out.println("myint = " + myInt.get());

    }

    public static void Increment(Integer n) {
        //NO.  this doesn't work because a new reference is being assigned
        //and references are passed by value in java
        n++;
    }

    public static void Increment(MyIntegerObj n) {
        //this works because we're still operating on the same object
        //no new reference was assigned to n here.
        n.plusplus();   //I didn't know how to implement a ++ operator...
    }
}

所有這些的結果是 n=0。 整數 n 是一個對象,因此通過引用傳遞,那么為什么增量沒有反映在調用方方法(main)中? 我預計輸出為 n=0 n=1 n=2 等等...

更新:注意我更新了上面的代碼示例。 如果我理解正確,Jon Skeet 回答了為什么 myInt 會增加而 n 不會增加的問題。 這是因為 n 正在獲取在 Increment 方法中分配的新引用。 但是 myInt 沒有被分配一個新的引用,因為它正在調用一個成員函數。

這聽起來像我理解正確嗎哈哈?

不,對象不是通過引用傳遞的。 引用是按值傳遞的 - 有很大的不同。 Integer是不可變類型,因此您不能在方法中更改值。

你的n++; 聲明是有效的

n = Integer.valueOf(n.intValue() + 1);

因此,它為Increment的變量n分配了一個不同的值 - 但由於 Java只有按值傳遞,這不會影響調用方法中n的值。

編輯:回答您的更新:沒錯。 大概您的“MyIntegerObj”類型是可變的,並且在您調用plusplus()時會更改其內部狀態。 哦,不要費心四處尋找如何實現運算符 - Java 不支持用戶定義的運算符。

您可以使用java.util.concurrent.atomicAtomicInteger 它有一個適合您展示的 'incrementAndGet' 方法。

您正在尋找類似於 C++ 的參考或 C# 的輸出參數的內容。 Java(和許多其他語言)不支持這一點。

這種類型的行為通常是通過將方法從 void 更改為(在這種情況下)int 來實現的: public static int increment(int n) { return ++n; } public static int increment(int n) { return ++n; }

如果該方法已經返回某些內容,那么您可以創建一個具有兩個字段(甚至可以是公共字段)的新類:原始返回值和 n 的新值。

或者,您也可以將整數包裝在通用 Cell 類中。 你只需要編寫一次這個 Cell 類:

public class Cell<T> {
  public Cell(T t) { value = t; }
  public void set(T t) { value = t; }
  public T get() { return value; }
}

然后,您可以在想要更改原語的方法的所有情況下使用它:

public static void increment(Cell<Integer> n) {
  n.set(n.get()++);
}

Cell<Integer> n = new Cell<Integer>(0);
increment(n);
increment(n);
increment(n);
System.out.println(n.get()); // Output: 3

正如 Jon Skeet 所提到的,Java 中的所有方法都是按值傳遞,而不是按引用傳遞。 由於引用類型是按值傳遞的,因此函數體內的內容是引用的副本 - 此副本和原始引用都指向相同的值。

但是,如果您在函數體內重新分配副本,它將對程序的其余部分沒有影響,因為該副本將在函數退出時超出范圍。

但是考慮到您實際上並不需要通過引用來做您想做的事情。 例如,您不需要增加Integer的方法 - 您只需在代碼中需要增加的點處增加它即可。

對於更復雜的類型,例如在對象上設置某些屬性,您正在使用的對象可能是可變的; 在這種情況下,引用的副本就可以正常工作,因為自動取消引用將使您找到您正在調用其 setter 的原始對象。

旁注:以我的拙見,在 Integer 對象上編寫 n++ 非常具有誤導性。 這依賴於 Java 的一項稱為“自動裝箱”的功能,它將原語轉換為相應的裝箱對象——比如 int 到 Integer 或 boolean 到 Boolean——自動且沒有警告。 坦率地說,我認為這是一個糟糕的功能。 是的,有時它會自動為您進行方便的轉換,從而使您的生活變得更簡單,但它也可以執行您不打算或沒有意識到正在發生的轉換,並產生意想不到的副作用。

無論如何,有兩種方法可以完成您顯然想要做的事情:

一:讓增量函數返回一個帶有更新值的新整數。 喜歡:

   public Integer increment(Integer n)
    {
      Integer nPlus=Integer.valueOf(n.intValue()+1);
      return nPlus;
    }

然后調用它:

Integer n=Integer.valueOf(0);
n=increment(n); // now n==1
n=increment(n); // now n==2

等等。

二:創建自己的類,類似於 Integer 但它是可變的。 喜歡:

class MutableInteger
{
  int value;
  public MutableInteger(int n)
  {
    value=n;
  }
  public void increment()
  {
    ++value;
  }
  ... whatever other functions you need ...
}

當然,最大的收獲是您幾乎必須重新發明 Integer 類。

你不能。 Java 是嚴格按值傳遞的。

http://javadude.com/articles/passbyvalue.htm

您的選擇是將整數包裝在一個對象(或數組)中,傳入並更新,返回一個值,或者使整數成為類/實例變量。

哪個更好取決於具體情況。

正如DerMike提到的,您可以按如下方式實現:

public void doStuff() {
  AtomicInteger i = new AtomicInteger(0);
  increment(i);
  System.out.println(i);
 }

  public void increment(AtomicInteger i) {
    i.set(i.get() + 1);
 }

Integer是一個值對象,這意味着它的值不能改變。

請注意, n++等效於n = n + 1 您只是在更改局部變量n引用的值,而不是n本身的值。

請參閱 AtomicInteger: http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html

您可以使用這個 java.util.concurrent 類來實現線程安全。

public class passByReferenceExample {
    static void incrementIt(Long b[]){
        Long c = b[0];
        c=c+1;
        b[0]=c;

    }
    public static void main(String[] args) {
        Long a[]={1L};  

        System.out.println("Before calling IncrementIt() : " + a[0]);
        System.out.println();
        incrementIt(a);
        System.out.println("after first call to incrementIt() : " + a[0]);
        incrementIt(a);
        System.out.println("after second call to incrementIt(): "+ a[0]);
        incrementIt(a);
        System.out.println("after third call to incrementIt() : "+ a[0]);
        incrementIt(a);
        System.out.println("after fourth  call to incrementIt(): "+ a[0]);    
    }
}

輸出:

Before calling IncrementIt() : 1

after first call to incrementIt() : 2
after second call to incrementIt(): 3
after third call to incrementIt() : 4
after fourth  call to incrementIt(): 5

暫無
暫無

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

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