Maison >Java >javaDidacticiel >Analyse approfondie du déballage Java

Analyse approfondie du déballage Java

高洛峰
高洛峰original
2017-01-24 13:57:281179parcourir

Regardons d'abord un morceau de code :

public class Main{
  public static void main(String[] args){
 
    Integer num1 = 100;
    Integer num2 = 100;
    Integer num3 = 200;
    Integer num4 = 200;
 
    '''//输出结果'''
    System.out.println(num1==num2);
    System.out.println(num3==num4);
  }
}


Devinez quel est le résultat ?

Beaucoup de gens penseront que les résultats sont tous vrais, mais les résultats ne sont pas comme ça

vrai
faux

Pourquoi est-ce le résultat ? Si les résultats sont expliqués en termes de mémoire, num1 et num2 pointent vers le même objet, tandis que num3 et num4 pointent vers des objets différents. Ensuite, je vais vous dire pourquoi. Jetez un œil au code source de la méthode valueof de type Integer :

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


L'implémentation. de IntegerCache :

&#39;&#39;&#39;// IntegerCache,一个内部类,注意它的属性都是定义为static final&#39;&#39;&#39;
  private static class IntegerCache {
    static final int high; &#39;&#39;&#39;//缓存上界,暂为null&#39;&#39;&#39;
    static final Integer cache[]; &#39;&#39;&#39;//缓存的整型数组&#39;&#39;&#39;
 
    &#39;&#39;&#39;// 块,为什么定义为块&#39;&#39;&#39;
    static {
      final int low = -128; &#39;&#39;&#39;// 缓存下界,不可变了。只有上界可以改变&#39;&#39;&#39;
 
      &#39;&#39;&#39;// high value may be configured by property&#39;&#39;&#39;
      &#39;&#39;&#39;// h值,可以通过设置jdk的AutoBoxCacheMax参数调整(以下有解释),自动缓存区间设置为[-128,N]。注意区间的下界是固定&#39;&#39;&#39;
      int h = 127;
 
      if (integerCacheHighPropValue != null) {
        &#39;&#39;&#39;// Use Long.decode here to avoid invoking methods that&#39;&#39;&#39;
        &#39;&#39;&#39;// require Integer&#39;s autoboxing cache to be initialized&#39;&#39;&#39;
        // 通过解码integerCacheHighPropValue,而得到一个候选的上界值&#39;&#39;&#39;
        int i = Long.decode(integerCacheHighPropValue).intValue();
        &#39;&#39;&#39;// 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE&#39;&#39;&#39;
        i = Math.max(i, 127);  
        &#39;&#39;&#39;// Maximum array size is Integer.MAX_VALUE&#39;&#39;&#39;
        h = Math.min(i, Integer.MAX_VALUE - -low);
      }
      high = h; &#39;&#39;&#39;//上界确定&#39;&#39;&#39;
      &#39;&#39;&#39;// 就可以创建缓存块,注意缓存数组大小&#39;&#39;&#39;
      cache = new Integer[(high - low) + 1]; //
      int j = low;
      for(int k = 0; k < cache.length; k++)
        cache[k] = new Integer(j++); &#39;&#39;&#39;// -128到high值逐一分配到缓存数组&#39;&#39;&#39;
    }
 
    private IntegerCache() {}
  }


On peut voir à partir de ces deux morceaux de code que lors de la création d'un objet de type Integer via la méthode valueof, le La plage de valeurs est [-128,127] et la valeur Dans cette plage, le pointeur pointe vers une référence d'objet qui existe déjà dans IntegerCache.cache. Lorsque la valeur dépasse cette plage, un nouvel objet est créé.

Une chose à noter est que tous les types ne sont pas dans cette gamme. Regardez le type Double :

public class Main{
  public static void main(String[] args){
 
    Double i1 = 100.0;
    Double i2 = 100.0;
    Double i3 = 200.0;
    Double i4 = 200.0;
 
    System.out.println(i1==i2);
    System.out.println(i3==i4);
  }
}


Le résultat final :

false
false

Plus précisément, pourquoi ce résultat se produit-il Vous pouvez jeter un œil à l'implémentation de la méthode Double valueof dans le code source, qui est différente ? à partir de la méthode Integer valueof. La différence est que le nombre de valeurs entières dans une certaine plage est limité, mais pas les nombres à virgule flottante.

Notez que l'implémentation de la méthode valueOf des classes Integer, Short, Byte, Character et Long est similaire.
L'implémentation de la méthode valueOf de Double et Float est similaire.

Tiré vers le bas, et le résultat de type booléen a deux Vrai ou Faux. Regardez directement le code source :

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
  }


et VRAI et FAUX sont définis comme ceci :

public static final Boolean TRUE = new Boolean(true);
 
&#39;&#39;&#39;/** &#39;&#39;&#39;
&#39;&#39;&#39;* The <code>Boolean</code> object corresponding to the primitive &#39;&#39;&#39;
&#39;&#39;&#39;* value <code>false</code>. &#39;&#39;&#39;
&#39;&#39;&#39;*/&#39;&#39;&#39;
public static final Boolean FALSE = new Boolean(false);


Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'apprentissage de chacun. J'espère également que tout le monde soutiendra le site Web PHP chinois.

Pour plus d'articles liés à une analyse approfondie du unboxing Java, veuillez faire attention au site Web PHP chinois !

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