six*_*ude 55 java integer pass-by-reference
我希望有人可以为我澄清这里发生的事情.我在整数类中挖了一下但因为整数覆盖了+运算符我无法弄清楚出了什么问题.我的问题在于这一行:
Integer i = 0;
i = i + 1; // ? I think that this is somehow creating a new object!
Run Code Online (Sandbox Code Playgroud)
这是我的推理:我知道java是通过值传递(或通过引用值传递),所以我认为在下面的示例中,每次都应该递增整数对象.
public class PassByReference {
public static Integer inc(Integer i) {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println("Inc: "+i);
return i;
}
public static void main(String[] args) {
Integer integer = new Integer(0);
for (int i =0; i<10; i++){
inc(integer);
System.out.println("main: "+integer);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的预期输出:
Inc: 1 main: 1 Inc: 2 main: 2 Inc: 3 main: 3 Inc: 4 main: 4 Inc: 5 main: 5 Inc: 6 main: 6 ...
这是实际输出.
Inc: 1 main: 0 Inc: 1 main: 0 Inc: 1 main: 0 ...
它为什么会这样?
Bal*_*usC 55
有两个问题:
Integer#set(i).否则你可以利用它.要使其工作,您需要重新分配方法的返回值inc().
integer = inc(integer);
Run Code Online (Sandbox Code Playgroud)
要了解更多关于传递值的信息,这是另一个例子:
public static void main(String... args) {
String[] strings = new String[] { "foo", "bar" };
changeReference(strings);
System.out.println(Arrays.toString(strings)); // still [foo, bar]
changeValue(strings);
System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
strings[1] = "foo";
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*kos 18
整数是不可变的.您可以在自定义包装类中包装int.
class WrapInt{
int value;
}
WrapInt theInt = new WrapInt();
inc(theInt);
System.out.println("main: "+theInt.value);
Run Code Online (Sandbox Code Playgroud)
Ris*_*Dua 15
有两种方法可以通过引用传递
这是一个示例代码:
public class Test {
public static void main(String args[]) {
Integer a = new Integer(1);
Integer b = a;
Test.modify(a);
System.out.println(a);
System.out.println(b);
IntegerObj ao = new IntegerObj(1);
IntegerObj bo = ao;
Test.modify(ao);
System.out.println(ao.value);
System.out.println(bo.value);
}
static void modify(Integer x) {
x=7;
}
static void modify(IntegerObj x) {
x.value=7;
}
}
class IntegerObj {
int value;
IntegerObj(int val) {
this.value = val;
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
1
7
7
Run Code Online (Sandbox Code Playgroud)
小智 15
上面的答案很好地解释了OP的实际问题.
如果有人需要传递需要全局更新的数字,请使用AtomicInteger()而不是创建建议的各种包装类或依赖第三方库.
的AtomicInteger()当然是主要用于线程安全的访问,但如果对性能的影响是没有问题,为什么不利用这个内置类.额外的好处当然是明显的线程安全性.
import java.util.concurrent.atomic.AtomicInteger
Run Code Online (Sandbox Code Playgroud)
rsp*_*rsp 12
你在这里看到的不是一个重载的+oparator,而是自动装箱行为.该Integer班是不可改变的,你的代码:
Integer i = 0;
i = i + 1;
Run Code Online (Sandbox Code Playgroud)
编译器(在自动装箱后)看到:
Integer i = Integer.valueOf(0);
i = Integer.valueOf(i.intValue() + 1);
Run Code Online (Sandbox Code Playgroud)
所以你的结论是正确的,Integer实例是改变的,但不是偷偷摸摸的 - 它与Java语言定义一致:-)
你在这里是对的:
Integer i = 0;
i = i + 1; // <- I think that this is somehow creating a new object!
Run Code Online (Sandbox Code Playgroud)
第一:整数是不可变的.
第二:Integer类没有覆盖+运算符,在该行中涉及自动装箱和自动装箱(在旧版本的Java中,您会在上面的行中收到错误).
编写i + 1编译器时,首先将Integer转换为(基元)int以执行添加:autounboxing.接下来,i = <some int>编译器将转换int为(新)Integer:autoboxing.
所以+实际上是应用于原始ints.
| 归档时间: |
|
| 查看次数: |
86051 次 |
| 最近记录: |