如何从另一种方法增加java中的类整数引用值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2208943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Increment a class Integer references value in java from another method
提问by cchampion
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...
}
}
The result for all of those is n=0. Integer n is an object and therefore passed by reference, so why isn't the increment reflected back in the caller method (main)? I expected output to be n=0 n=1 n=2 etc...
所有这些的结果是 n=0。整数 n 是一个对象,因此通过引用传递,那么为什么增量没有反映在调用方方法(main)中?我预计输出为 n=0 n=1 n=2 等等...
UPDATE: Notice I updated the code example above. If I'm understanding correctly, Jon Skeet answered the question of why myInt would increment and why n does not. It is because n is getting a new reference assigned in the Increment method. But myInt does NOT get assigned a new reference since it's calling a member function.
更新:注意我更新了上面的代码示例。如果我理解正确,Jon Skeet 回答了为什么 myInt 会增加而 n 不会增加的问题。这是因为 n 正在获取在 Increment 方法中分配的新引用。但是 myInt 没有被分配一个新的引用,因为它正在调用一个成员函数。
Does that sound like I understand correctly lol ?
这听起来像我理解正确吗哈哈?
采纳答案by Jon Skeet
No, objects aren't passed by reference. References are passed by value - there's a big difference. Integer
is an immutable type, therefore you can't change the value within the method.
不,对象不是通过引用传递的。引用是按值传递的 - 有很大的不同。Integer
是不可变类型,因此您无法更改方法中的值。
Your n++;
statement is effectively
你的n++;
说法是有效的
n = Integer.valueOf(n.intValue() + 1);
So, that assigns a different value to the variable n
in Increment
- but as Java onlyhas pass-by-value, that doesn't affect the value of n
in the calling method.
因此,这为变量n
in分配了不同的值Increment
- 但由于 Java只有按值传递,这不会影响n
调用方法中的值。
EDIT: To answer your update: that's right. Presumably your "MyIntegerObj" type is mutable, and changes its internal state when you call plusplus()
. Oh, and don't bother looking around for how to implement an operator - Java doesn't support user-defined operators.
编辑:回答您的更新:没错。大概您的“MyIntegerObj”类型是可变的,并且在您调用plusplus()
. 哦,不要费心四处寻找如何实现运算符 - Java 不支持用户定义的运算符。
回答by Itay Maman
You are looking for something similar to C++'s reference or to C#' out parameter. Java (and many other languages) does not support this.
您正在寻找类似于 C++ 的参考或 C# 的输出参数的内容。Java(和许多其他语言)不支持这一点。
This type of behavior is typically achieved by changing the method from void to (in this case) int: public static int increment(int n) { return ++n; }
这种类型的行为通常是通过将方法从 void 更改为(在这种情况下)int 来实现的: public static int increment(int n) { return ++n; }
If the method is already returning something then you can create a new class that has two fields (can even be public): the original return value and the new value of n.
如果该方法已经返回某些内容,那么您可以创建一个具有两个字段(甚至可以是公共字段)的新类:原始返回值和 n 的新值。
Alternatively, you can also wrap the integer inside a generic Cell class. You only need to write this Cell class once:
或者,您也可以将整数包装在通用 Cell 类中。你只需要编写一次这个 Cell 类:
public class Cell<T> {
public Cell(T t) { value = t; }
public void set(T t) { value = t; }
public T get() { return value; }
}
You can then use it in all situations where you want to a method to change a primitive:
然后,您可以在想要更改原语的方法的所有情况下使用它:
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
回答by DerMike
You could use an AtomicInteger
from java.util.concurrent.atomic
. It has a 'incrementAndGet' method which is suitable for your showcase.
您可以使用AtomicInteger
from java.util.concurrent.atomic
。它有一个适合您展示的 'incrementAndGet' 方法。
回答by Kevin
Integer
is a value objectwhich means that is value can't change.
Integer
是一个值对象,这意味着值不能改变。
Note that n++
is the equivalent of n = n + 1
. You're just changing the value referred to by the local variable n
, not the value of n
itself.
请注意,n++
它等效于n = n + 1
。您只是在更改局部变量引用的值n
,而不是其n
本身的值。
回答by Joe
You can't. Java is strictly pass-by-value.
你不能。Java 是严格按值传递的。
See http://javadude.com/articles/passbyvalue.htm
见http://javadude.com/articles/passbyvalue.htm
Your choices are to wrap the integer in an object (or array), pass that in and update, return a value, or make the integer a class/instance variable.
您的选择是将整数包装在一个对象(或数组)中,传入并更新,返回一个值,或者使整数成为类/实例变量。
Which is better depends on the situation.
哪个更好取决于具体情况。
回答by danben
As Jon Skeet mentioned, all methods in Java are pass-by-value, not pass-by-reference. Since reference types are passed by value, what you have inside the function body is a copy of the reference - this copy and the original reference both point to the same value.
正如 Jon Skeet 所提到的,Java 中的所有方法都是按值传递,而不是按引用传递。由于引用类型是按值传递的,因此函数体内的内容是引用的副本 - 此副本和原始引用都指向相同的值。
However, if you reassign the copy inside the function body, it will have no effect on the rest of your program as that copy will go out of scope when the function exits.
但是,如果您在函数体内重新分配副本,它将对程序的其余部分没有影响,因为该副本将在函数退出时超出范围。
But consider that you don't really need pass-by-reference to do what you want to do. For instance, you don't need a method to increment an Integer
- you can just increment it at the point in your code where it needs to be incremented.
但是考虑到您实际上并不需要通过引用来做您想做的事情。例如,您不需要增加 an 的方法Integer
- 您只需在代码中需要增加的点处增加它即可。
For more complex types, like setting some property on an Object, the Object you are working with is likely mutable; in that case a copy of the reference works just fine, since the automatic dereference will get you to the original object whose setter you are calling.
对于更复杂的类型,例如在对象上设置某些属性,您正在使用的对象可能是可变的;在这种情况下,引用的副本就可以正常工作,因为自动取消引用将使您找到您正在调用其 setter 的原始对象。
回答by Jay
Side note: In my humble opinion, writing n++ on an Integer object is extremely misleading. This relies on a feature of Java called "autoboxing" where it converts primitives to their corresponding boxing objects -- like int to Integer or boolean to Boolean -- automatically and without warning. Frankly I think it's a bad feature. Yes, sometimes it makes your life simpler by automatically doing a handy conversion for you, but it can also do conversions that you did not intend and do not realize are happening, with unintended side effects.
旁注:以我的拙见,在 Integer 对象上编写 n++ 非常具有误导性。这依赖于 Java 的一项称为“自动装箱”的功能,它将原语转换为相应的装箱对象——比如 int 到 Integer 或 boolean 到 Boolean——自动且没有警告。坦率地说,我认为这是一个糟糕的功能。是的,有时它会自动为您进行方便的转换,从而使您的生活变得更简单,但它也可以执行您不打算或没有意识到正在发生的转换,并产生意想不到的副作用。
Anyway, there are two ways to accomplish what you are apparently trying to do:
无论如何,有两种方法可以完成您显然想要做的事情:
One: Have the increment function return a new Integer with the updated value. Like:
一:让增量函数返回一个带有更新值的新整数。喜欢:
public Integer increment(Integer n)
{
Integer nPlus=Integer.valueOf(n.intValue()+1);
return nPlus;
}
then call it with:
然后调用它:
Integer n=Integer.valueOf(0);
n=increment(n); // now n==1
n=increment(n); // now n==2
Etc.
等等。
Two: Create your own class that resembles Integer but that is mutable. Like:
二:创建自己的类,类似于 Integer 但它是可变的。喜欢:
class MutableInteger
{
int value;
public MutableInteger(int n)
{
value=n;
}
public void increment()
{
++value;
}
... whatever other functions you need ...
}
Of course the big catch to this is that you pretty much have to re-invent the Integer class.
当然,最大的收获是您几乎必须重新发明 Integer 类。
回答by JareQ
As DerMikementioned you can achieve this as follows:
正如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);
}
回答by cjaniake
See AtomicInteger: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html
请参阅 AtomicInteger:http: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html
You can do it thread-safe using this java.util.concurrent class.
您可以使用这个 java.util.concurrent 类来实现线程安全。
回答by Suresh
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]);
}
}
output:
输出:
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