Heim  >  Artikel  >  Java  >  Eine detaillierte Zusammenfassung der häufigsten Fehler zwischen Long und Integer in Java

Eine detaillierte Zusammenfassung der häufigsten Fehler zwischen Long und Integer in Java

高洛峰
高洛峰Original
2017-01-22 10:22:231326Durchsuche

Nachdem ich heute Findbugs zum Scannen des Projekts verwendet habe, habe ich viele Schwachstellen mit hohem Risiko gefunden. Eine der häufigsten ist die direkte Verwendung von == beim Vergleich zweier Long- oder Integer-Werte. Tatsächlich ist das falsch.

Weil Long und Ineger sowohl Verpackungstypen als auch Objekte sind. Anstelle der gewöhnlichen Typen long und int müssen sie beim Vergleich gleich sein, oder Sie können zuerst die Methode longValue () oder intValue () verwenden, um ihre Grundtypwerte abzurufen, und dann == zum Vergleich verwenden.

Aber es gibt einen Sonderfall: Sowohl Long- als auch Integer-Cache-Objekte -128~127. Sie können sehen, dass es im Quellcode vom Typ Long eine LongCache-Klasse gibt. Der Code lautet wie folgt:

private static class LongCache {
 private LongCache(){}
 
 static final Long cache[] = new Long[-(-128) + 127 + 1];
 
 static {
   for(int i = 0; i < cache.length; i++)
 cache[i] = new Long(i - 128);
 }
  }

Schauen wir uns zunächst dieses Beispiel an:

public class Test05 {
 
  public static void main(String[] args) {
    Long a = 5L;
    Long b = 5L;
 
    System.out.println("a == b ? " + (a == b));
 
    Long c = 129L;
    Long d = 129L;
    System.out.println("c == d ? " + (c == d));
  }
}

Das gedruckte Ergebnis ist:

a == b ? true
c == d ? false

Grund

Schauen wir uns zunächst an, wie Long a = 5L einen Basistyp umschließt long in ein Objekt Long.

Sie können eine Testklasse schreiben und diese dann dekompilieren, um zu sehen, wie Java einen Befehl wie Long a = 5L analysiert.

Die Testklasse lautet wie folgt:

public class Test06 {
  Long l = 3L;
}

Verwenden Sie dann javap -verbose Test06, um die Dekompilierungsergebnisse anzuzeigen:

{
java.lang.Long l;
 
public com.spring.test.Test06();
 Code:
  Stack=3, Locals=1, Args_size=1
  0:  aload_0
  1:  invokespecial  #10; //Method java/lang/Object."<init>":()V
  4:  aload_0
  5:  ldc2_w #12; //long 3l
  8:  invokestatic  #14; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
  11: putfield    #20; //Field l:Ljava/lang/Long;
  14: return
 LineNumberTable:
  line 3: 0
  line 5: 4
  line 3: 14
 
 LocalVariableTable:
  Start Length Slot Name  Signature
  0   15   0  this    Lcom/spring/test/Test06;
 
 
}

Aus 8 im Code geht hervor, dass eine Klassenmethode Long.valueOf(Long) von Long aufgerufen wird. Die Schlussfolgerung, die daraus gezogen werden kann, ist also folgende Long a = 5L Eigentlich gleich Long a = Long.valueOf(5);

Dann schauen Sie sich an, wie die Long.valueOf()-Methode definiert ist:

public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
  return LongCache.cache[(int)l + offset];
}
   return new Long(l);
 }


Es ist auf den ersten Blick klar, dass, wenn der Wert des Basistyps zwischen -128~127 liegt, das zwischengespeicherte Objekt direkt aus dem LongCache abgerufen und zurückgegeben wird, andernfalls ein neues Long-Objekt wird zurückgegeben.

Jetzt ist es nicht schwer, die Ergebnisse der Test05-Programmausführung zu verstehen, da a und b innerhalb von -127 bis 128 gleich 5 sind, also beide ein Long-Objekt sind, das direkt von LongCache zurückgegeben wird Wenn == zum Vergleich verwendet wird, sind sie gleich (für Objekttypen vergleicht == die Adressen im Heap, auf die die Referenzen der beiden Objekte verweisen), und c und d sind gleich 129 und nicht zwischen -127 und 128 Es handelt sich also um zwei neue Long-Objekte, die separat erstellt wurden. Natürlich sind sie beim Vergleich mit == nicht gleich.

Long schreibt die Methode equal neu:

public boolean equals(Object obj) {
 if (obj instanceof Long) {
   return value == ((Long)obj).longValue();
 }
 return false;
  }

Es erhält zuerst den Wert des Basistyps long des Long-Objekts über die Methode .longValue() und dann vergleicht es.

Für den Vergleich zwischen Integer und Long ist es daher am besten, Gleichheit zu verwenden, um sicherzustellen, dass wir die gewünschten Ergebnisse erhalten.

Integer ist dasselbe wie Long, daher werde ich hier kein Beispiel geben.

Die obige Zusammenfassung der häufigsten Fehler von Long und Integer in Java ist der gesamte vom Herausgeber geteilte Inhalt. Ich hoffe, dass er Ihnen eine Referenz geben kann, und ich hoffe auch, dass jeder die chinesische PHP-Website unterstützt.

Eine detailliertere Zusammenfassung der häufigsten Fehler, die Long und Integer in Java machen, finden Sie auf der chinesischen PHP-Website für verwandte Artikel!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn