Maison  >  Article  >  Java  >  Un résumé détaillé des erreurs courantes entre Long et Integer en Java

Un résumé détaillé des erreurs courantes entre Long et Integer en Java

高洛峰
高洛峰original
2017-01-22 10:22:231387parcourir

Après avoir utilisé findbugs pour analyser le projet aujourd'hui, j'ai trouvé de nombreuses vulnérabilités à haut risque. L'une des plus courantes est l'utilisation directe de == lors de la comparaison de deux Long ou Integer. En fait, c'est faux.

Parce que Long et Ineger sont à la fois des types d'emballages et des objets. Au lieu des types ordinaires long et int, ils doivent utiliser des égaux lors de la comparaison, ou vous pouvez d'abord utiliser la méthode longValue() ou intValue() pour obtenir leurs valeurs de type de base, puis utiliser == pour comparer.

Mais il existe un cas particulier. En fait, les objets Long et Integer cachent -128~127. Vous pouvez voir qu'il existe une classe LongCache dans le code source de type Long. Le code est le suivant :

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

Jetons d'abord un coup d'œil à cet exemple :

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

Le résultat imprimé est :

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

Raison

Tout d'abord, regardons Long a = 5L comment il enveloppe un type de base ; long dans un objet Long.

Vous pouvez écrire une classe de test puis la décompiler pour voir comment Java analyse une commande comme Long a = 5L.

La classe de test est la suivante :

public class Test06 {
  Long l = 3L;
}

Utilisez ensuite javap -verbose Test06 pour voir les résultats de la décompilation :

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

On peut voir à partir de 8 dans Code qu'une méthode de classe Long.valueOf(Long) de Long est appelée, donc la conclusion qui peut être tirée est que Long a = 5L En fait égal à Long a = Long.valueOf(5);

Regardez ensuite comment la méthode Long.valueOf() est définie :

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


Il est clair en un coup d'œil que si la valeur du type de base est comprise entre -128~127, l'objet mis en cache sera directement récupéré du LongCache et renvoyé, sinon un nouvel objet Long sera restitué.

Maintenant, il n'est pas difficile de comprendre les résultats de l'exécution du programme Test05, car a et b sont égaux à 5, entre -127~128, ce sont donc tous les deux des objets Long renvoyés directement depuis LongCache, donc ils sont Lorsque vous utilisez == pour la comparaison, ils sont égaux (pour les types d'objets, == compare les adresses dans le tas vers lesquelles pointent les références des deux objets), et c et d sont égaux à 129, et non entre -127~128, ce sont donc deux nouveaux objets Long créés séparément. Naturellement, ils ne sont pas égaux lorsqu'ils sont comparés en utilisant ==.

Long réécrit la méthode equals :

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

Il obtient d'abord la valeur du type de base long de l'objet Long via la méthode .longValue() puis le compare.

Donc, pour la comparaison entre Integer et Long, il est préférable d'utiliser des valeurs égales pour garantir que nous obtenons le résultat souhaité.

Integer est identique à Long, donc je ne donnerai pas d'exemple ici.

Le résumé ci-dessus des erreurs courantes de Long et Integer en Java est tout le contenu partagé par l'éditeur. J'espère qu'il pourra vous donner une référence, et j'espère également que tout le monde soutiendra le site Web PHP chinois.

Pour un résumé plus détaillé des erreurs courantes commises par Long et Integer en Java, veuillez prêter attention au site Web PHP chinois pour les articles connexes !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn