为什么输出下面的代码1而不是0?

问题描述:

@Test 
    public void test(){ 
     Map<String, Integer> a = new HashMap<>(); 
     a.put("x", new Integer(0)); 
     Integer i = a.get("x"); 
     a.put("x", i++); 
     i = a.get("x"); 
     a.put("x", i++); 
     i = a.get("x"); 
     a.put("x", i++); 
     System.err.println(i); 
    } 

上面的代码的输出是1而不是0我不明白为什么。有人可以解释发生了什么事吗? Java的一些字节码优化导致这种状态?为什么输出下面的代码1而不是0?

+1

你增量,所以你为什么想到要打印0? – tkausl

+1

请使用调试器。这是了解代码片段工作原理的有效方法。 –

因为i++返回i递增之前i。见我的评论:

Map<String, Integer> a = new HashMap<>(); 
a.put("x", new Integer(0)); // x=0 
Integer i = a.get("x");  // i=0 
a.put("x", i++);   // x=0, i=1 
i = a.get("x");    // i=0 
a.put("x", i++);   // x=0, i=1 
i = a.get("x");    // i=0 
a.put("x", i++);   // x=0, i=1 
System.err.println(i); 

下面是相关的部分从documentation of unary operators

递增/递减运营商可以前(前缀)被应用或之后(后缀)的操作。代码result++;++result;的结果都会以1递增。

唯一的区别是前缀版本(++result)评估为递增值,而后缀版本(result++)评估为原始值。

如果您只是执行一个简单的递增/递减,那么选择哪个版本并不重要。但是如果你在更大的表达式中使用这个运算符,那么你选择的运算符可能会有很大的不同。

是的,它应该是一个。最后的声明是a.put("x", i++);,因此您将0的值存入您的Map,但您随后增加i。如果你最后的陈述是i = a.get("x");你会得到0

+0

谢谢。得到它了! – user1615664

您使用后递增,因此首先读取i的值,然后递增。

@Test 
public void test(){ 
    Map<String, Integer> a = new HashMap<>(); 
    a.put("x", new Integer(0)); 
    Integer i = a.get("x"); // i is 0 
    a.put("x", i++); // x = 0; then i increment 
    i = a.get("x"); // i is reset to 0 
    a.put("x", i++); // x = 0; then i increment 
    i = a.get("x"); // i is reset to 0 
    a.put("x", i++); // x = 0; then i increment 
    System.err.println(i); // i == 1 
} 

解释直列:

@Test 
public void test(){ 
    Map<String, Integer> a = new HashMap<>(); 
    a.put("x", new Integer(0)); // Store Integer(0) 
    Integer i = a.get("x");  // Get it 
    a.put("x", i++);   // Unbox it, rebox it, store it again (still 0); increment it afterward 
    i = a.get("x");    // Same again 
    a.put("x", i++);   // ... 
    i = a.get("x");    // ... 
    a.put("x", i++);   // Unbox it, rebox it, store it again (still 0); increment it afterward 
    System.err.println(i);  // Show it; contains the *incremented* value 
} 

由于存储的值始终为0,你得到它在年底增加它,你最终以1

让我们通过这个一步一步:

Integer i = a.get("x"); 

i是0

a.put("x", i++); 

地图中的“x”不会更改,因为您将其设置为i(= 0)并在设置后增加。

i = a.get("x"); 

,我再次得到,因为依然什么存储在“X”

a.put("x", i++); 

同样的事情上面这就是唯一的“X”设置为0

后设置为0,我被设置为一
i = a.get("x"); 

I = 0

a.put("x", i++); 

现在我是1,您打印

System.err.println(i); 

你的最后一句话我增加1个产生的I = 1