![](/img/trans.png)
[英]How to invoke method in another class and return value from it in 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.atomic
的AtomicInteger
。 它有一個適合您展示的 '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.