Domanda

Considera questo codice:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

Stampa:

false
true
false

Capisco il primo false, l'operatore == controlla solo se due riferimenti stanno lavorando sullo stesso oggetto, cosa che in questo caso non è possibile.

Il seguente true E false farmi grattare la testa.Perché Java dovrebbe prendere in considerazione i3 E i4 uguale ma i1 E i2 diverso?Entrambi sono stati incapsulati in Integer, non dovrebbero Entrambi valutare come falso?C’è una ragione pratica per questa incoerenza?

È stato utile?

Soluzione

Autoboxing di primitive in oggetti (come in uso nel proprio chiamate a method utilizza una cache di piccoli valori. Dal sezione Java Language Specification 5.1.7 :

  

Se il valore p essere inscatolato è vero,   falso, un byte, un char nella gamma   \ U0000 a \ u007F, o un int o corto   numero compreso tra -128 e 127, poi lasciare   r1 e r2 essere i risultati di due qualsiasi   conversioni boxe di p. E 'sempre   il caso che r1 == r2.

La parte discussione della specifica immediatamente successivo a quello è interessante anche. In particolare una JVM può memorizzare nella cache più valori se si vuole - non si può essere sicuri dei risultati di fare:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

Altri suggerimenti

Quando autoboxing, interi fra -128 e 127 vengono memorizzati nella cache, e lo stesso oggetto involucro viene restituito. Lo stesso con valori booleani e valori char tra \ u0000 e \ u007F

Questo è ciò che si ottiene la maggior parte del tempo, tuttavia, dipende sull'attuazione JVM.

Questo perché la boxe rende interi di sotto di un certo valore (128, credo) si riferiscono a qualche oggetto precostruito, e valori più elevati per i nuovi oggetti.

usi autoboxing Integer.valueOf (i) , non new Integer (i), per costruire un oggetto della classe Integer.

Mentre gli altri hanno detto, valueOf () utilizza una cache, per lo più per l'efficienza dello spazio.

Non usare == sui tipi di riferimento, è quasi sempre un errore.

La classe intera contiene una cache di alcune istanze utilizzate di frequente.L'intervallo di valori generalmente varia da JVM a JVM (a volte è anche configurabile) ma in generale il codice rilevante è qualcosa del tipo:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

(codice da sole JDK 1.6)

questo è come l'internamento di stringhe, poiché risparmia memoria e consente l'uguaglianza dei test utilizzando un riferimento (ad es. == al posto di equivale)

Direi che l'involucro cerca di minimizzare il numero di interi oggetti e crea solo un oggetto che rappresenta 2 anche salvare la memoria.

Basta ricordarsi di non usare mai == sugli oggetti non si sa mai cosa succede.

Autoboxing utilizzare alcuni meccanismo di caching. Di solito non si dovrebbe mai fare affidamento su ==, utilizzare sempre equals per controllare l'uguaglianza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top