Come modificare l'aggiunta di interi in java?

Sep 03 2020

Quindi fondamentalmente stavo facendo delle ricerche perché ero curioso di vedere se poteva essere fatto e ho trovato questo codice:

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);
    }
}

Ero semplicemente curioso del motivo per cui l'istruzione printf ora restituisse 5, ma stampare l'intero n mi avrebbe dato 4.

Risposte

3 Sweeper Sep 04 2020 at 00:47

Java memorizza nella cache 256 Integeroggetti che rappresentano i numeri da -128 a 127. Quando un intviene inscatolato in un Integer, se il suo valore è compreso tra -128 e 127, Integerverrà utilizzato l' oggetto dalla cache. ( Scopri di più qui ). Il modo in cui la lingua lo fa è un dettaglio di implementazione. Nella tua versione di Java, memorizza questa cache in una classe interna in Integer, in un Integer[]campo chiamato cache. In qualche altra versione di Java, questo potrebbe cambiare, quindi il codice potrebbe non funzionare.

Ciò che la prima parte del codice sta facendo è ottenere la cache dei numeri interi e impostare l'indice 132 in modo che sia uguale all'indice 133. Poiché questo array inizia da -128, l'indice 132 corrisponderebbe a dove si trova 4 e l'indice 133 sarebbe dove 5 è. Ciò significa che hai sostituito 4 nella cache con un 5.

L'argomento printf, 2 + 2prima viene valutata a 4. Poi viene confezionato in un Integer. Questo perché printfaccetta solo un Objectcome secondo parametro. Poiché 4 è compreso tra -128 e 127, viene utilizzata la cache e si accede all'indice 132 dell'array, perché è lì che Integersarebbe stato il 4, se non hai modificato l'array. Ma hai modificato l'array, quindi ha ottenuto 5 invece.

D'altra parte, printlnstampa ancora 4 perché printlnha un sovraccarico che accetta int, quindi non si verifica alcun pugilato.

A proposito, non stai modificando "somma intera", stai solo modificando "boxing intero".