如何修改Java中的整数加法?

huangapple go评论55阅读模式
英文:

How to modify integer addition in java?

问题

基本上我在做一些研究,因为我很好奇是否可以做到,然后我找到了这段代码:

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        array[132] = array[133];

        int n = 2 + 2;
        System.out.println(n);
        System.out.printf("%d", 2 + 2);
    }
}

我只是好奇为什么printf语句现在会返回5,但打印整数n仍然会给我4。

英文:

So basically I was doing some research because I was curious to see if it could be done and I found this code:

import java.lang.reflect.Field;


public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        array[132] = array[133];

      int  n = 2+2;
      System.out.println(n);
      System.out.printf("%d",2 + 2);
    }
}

I was simply curious why the printf statement would now return 5, but printing integer n would sill give me 4.

答案1

得分: 3

Java缓存了表示从-128到127的256个Integer对象,当一个int被装箱为一个Integer时,如果其值在-128到127之间,将使用缓存中的Integer对象。这是语言的实现细节。在您的Java版本中,它将此缓存存储在Integer的一个内部类中,名为cacheInteger[]字段中。在其他某个版本的Java中,这可能会改变,因此您的代码可能会出错。

您的代码的第一部分所做的是获取整数缓存,并将索引132设置为与索引133相同。由于这个数组从-128开始,索引132对应于数字4的位置,索引133对应于数字5的位置。这意味着您已经用5替换了缓存中的4。

传递给printf的参数2 + 2首先被求值为4。然后它被装箱为一个Integer。这是因为printf只接受一个Object作为其第二个参数。因为4在-128到127之间,所以使用了缓存,并且访问了数组的索引132,因为如果您没有修改数组,Integer 4本应在那里。但是您已经修改了数组,所以它变成了5。

另一方面,println仍然打印4,因为println有一个接受int的重载,因此在那里不会进行装箱。

顺便说一下,您并没有修改"整数加法",您只是修改了"整数装箱"。

英文:

Java caches 256 Integer objects representing the numbers from -128 to 127. When an int gets boxed to an Integer, if its value is between -128 and 127, the Integer object from the cache will be used. (Learn more here). How the language does this is implementation detail. In your version of Java, it stores this cache in an inner class in Integer, in an Integer[] field called cache. In some other version of Java, this might change, so your code might break.

What the first part of your code is doing, is getting the integer cache, and setting index 132 to be the same as index 133. Since this array starts from -128, index 132 would correspond to where 4 is, and index 133 would be where 5 is. This means you have replaced 4 in the cache with a 5.

The argument to printf, 2 + 2, first gets evaluated to 4. Then it gets boxed to an Integer. This is because printf only accepts an Object as its second parameter. Because 4 is between -128 and 127, the cache is used, and index 132 of the array is accessed, because that's where the Integer 4 would have been, if you haven't modified the array. But you have modified the array, so it got 5 instead.

On the other hand, println still prints 4 because println has an overload that accepts int, so no boxing occurs there.

By the way, you are not modifying "integer addition", you are just modifying "integer boxing".

huangapple
  • 本文由 发表于 2020年9月4日 08:31:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63733340.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定