[JAVA] J'ai lu la source d'Integer

D'une manière ou d'une autre, j'ai décidé de lire également la source JDK. Cela dit, je n'ai pas le temps de lire attentivement chaque ligne, alors je l'ai lu brièvement et j'ai trouvé ce code. La dernière fois que j'ai lu la source de Short [http://qiita.com/hiuchida/items/c1b293eeb54b745dfb48), le prochain est Integer.

Classe entière

La classe Integer est une classe wrapper pour le type primitif int. Premièrement, les champs et les constructeurs. Eh bien, c'est une source que tout le monde peut imaginer.

Integer.java


    private final int value;

    public Integer(int value) {
        this.value = value;
    }

Classe IntegerCache

En fait, il existe une classe IntegerCache qui ne peut pas être vue dans javadoc.

Integer.java


    /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

Cela a changé avec Byte et Short. Puisque cette classe interne est privée, vous ne pouvez généralement pas lire ce qui est écrit dans le commentaire javadoc. Il semble que vous puissiez augmenter la limite supérieure de 127 avec l'option de démarrage -XX: AutoBoxCacheMax = size. Selon Numeric Cache, il a été ajouté à partir du JDK 1.6.

Vérifions la source du JDK 1.5.

Integer.java


    private static class IntegerCache {
        private IntegerCache(){}

        static final Integer cache[] = new Integer[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Integer(i - 128);
        }
    }

Oh, c'est rafraîchissant. Comme Byte et Short, il était de -128 à 127. Bien qu'il s'agisse d'IntegerCache, il est référencé par valueOf comme Byte et Short.

Integer.java


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

Comparer avec l'opérateur de comparaison ==

Comme pour Short, comparez les instances avec 127 et 128.

Main.java


	public static void main(String[] args) {
        int i00 = 127;
        Integer i01 = Integer.valueOf(i00);
        Integer i02 = i00;
        System.out.println(i01 == i02);
        int i10 = 128;
        Integer i11 = Integer.valueOf(i10);
        Integer i12 = i10;
        System.out.println(i11 == i12);
	}

Quand tu cours ...

$ java Main
true
false

$ java -XX:AutoBoxCacheMax=127 Main
true
false

$ java -XX:AutoBoxCacheMax=128 Main
true
true

Option de démarrage -XX: AutoBoxCacheMax fonctionne.

Source Hacker's Delight

Dans le javadoc traduit en japonais, "Notes sur l'implémentation: L'implémentation de la méthode" bit twiddling "(plusleversOneBit et numberOfTrailingZeros) est" Hacker's Delight "(Addison Wesley, 2002) par Henry S. Warren, Jr. ) C'est basé sur. "est ce qu'il lit. Puisqu'il s'agit du JDK 1.5, beaucoup d'entre vous le savent probablement, mais cherchons la source de la chaîne "HD".

Integer.java


    public static int highestOneBit(int i) {
        // HD, Figure 3-1
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        return i - (i >>> 1);
    }

    public static int lowestOneBit(int i) {
        // HD, Section 2-1
        return i & -i;
    }

    public static int numberOfLeadingZeros(int i) {
        // HD, Figure 5-6
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;
        return n;
    }

    public static int numberOfTrailingZeros(int i) {
        // HD, Figure 5-14
        int y;
        if (i == 0) return 32;
        int n = 31;
        y = i <<16; if (y != 0) { n = n -16; i = y; }
        y = i << 8; if (y != 0) { n = n - 8; i = y; }
        y = i << 4; if (y != 0) { n = n - 4; i = y; }
        y = i << 2; if (y != 0) { n = n - 2; i = y; }
        return n - ((i << 1) >>> 31);
    }

    public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }

    public static int reverse(int i) {
        // HD, Figure 7-1
        i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
        i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
        i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
        i = (i << 24) | ((i & 0xff00) << 8) |
            ((i >>> 8) & 0xff00) | (i >>> 24);
        return i;
    }

    public static int signum(int i) {
        // HD, Section 2-7
        return (i >> 31) | (-i >>> 31);
    }

bitCount ressemble à un peu quand vous regardez Algorithme pour compter / rechercher des bits. Cela semble être beaucoup plus rapide que de boucler et de compter par vous-même. Quand utilisez-vous le problème ... mostOneBit résolvait le problème et j'ai eu l'occasion de l'utiliser. → Concours de Noël 2016 / A --Array Sum

Méthodes ajoutées dans JDK 1.8

Il y en a beaucoup, alors je n'en ai ramassé que trois.

Integer.java


    public static int sum(int a, int b) {
        return a + b;
    }

    public static int max(int a, int b) {
        return Math.max(a, b);
    }

    public static int min(int a, int b) {
        return Math.min(a, b);
    }

Je n'en ai pas vraiment besoin. Si vous voulez quand même le faire, vous devriez créer une version int de Math.pow (). (1/13 postscript) Eh bien, si c'est sum, si c'est une méthode qui a été conçue comme sauter une exception quand elle déborde, elle a toujours de la valeur, mais qu'en est-il d'une méthode qui renvoie simplement a + b? Et comme il s'agit d'une classe Integer, les méthodes non statiques comme Integer add (Integer other) entrent très bien ... (1/13 postscript) @see java.util.function.BinaryOperator est écrit dans le commentaire javadoc, mais cela avait-il un sens?

méthode parseUnsignedInt

(1/13 postscript) Je l'ai sauté légèrement, mais je l'ai ajouté en regardant Long.parseUnsignedLong.

À partir de JDK 1.8, parseUnsignedInt a été ajouté. Java int n'est-il pas signé? Que signifie l'analyser non signé?

Integer.java


    public static int parseUnsignedInt(String s, int radix)
                throws NumberFormatException {
        if (s == null)  {
            throw new NumberFormatException("null");
        }

        int len = s.length();
        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar == '-') {
                throw new
                    NumberFormatException(String.format("Illegal leading minus sign " +
                                                       "on unsigned string %s.", s));
            } else {
                if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
                    (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
                    return parseInt(s, radix);
                } else {
                    long ell = Long.parseLong(s, radix);
                    if ((ell & 0xffff_ffff_0000_0000L) == 0) {
                        return (int) ell;
                    } else {
                        throw new
                            NumberFormatException(String.format("String value %s exceeds " +
                                                                "range of unsigned int.", s));
                    }
                }
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
    }

Je me suis demandé si je pouvais écrire 0xffff_ffff_0000_0000L, mais si c'était une valeur de seulement les 32 bits inférieurs, je le ferais avec int. En d'autres termes, même si le bit de code est défini, il sera converti en int, donc il sera négatif. Il analyse les non-signés, mais cela peut être négatif. C'est une excellente spécification.

Essayons.

Main.java


    public static void main(String[] args) {
        int i01 = Integer.parseUnsignedInt("2147483647");
        System.out.println(i01);
        int i02 = Integer.parseUnsignedInt("2147483648");
        System.out.println(i02);
        int i03 = Integer.parseUnsignedInt("4294967295");
        System.out.println(i03);
        int i04 = Integer.parseUnsignedInt("4294967296");
        System.out.println(i04);
    }

Quand tu cours ...

2147483647
-2147483648
-1
Exception in thread "main" java.lang.NumberFormatException: String value 4294967296 exceeds range of unsigned int.
	at java.lang.Integer.parseUnsignedInt(Integer.java:684)
	at java.lang.Integer.parseUnsignedInt(Integer.java:711)
	at Main.main(Main.java:9)

Le résultat est comme prévu, mais êtes-vous heureux? cette. Si vous souhaitez utiliser 32 bits complet, vous pouvez utiliser long.

finalement

Il y a parseUnsignedInt dans les méthodes ajoutées dans JDK 1.8, mais je pense qu'il existe de nombreuses méthodes statiques. (1/13 postscript) Il y avait 37 méthodes statiques publiques dans JDK 1.8. Je pense qu'il serait préférable de le séparer dans la classe IntegerUtil s'il existe une telle chose. Au fait, il était de 13 dans JDK 1.4. Il était une fois, je pensais que c'était un cours plus simple.

Soudain, j'ai remarqué que la largeur de l'onglet dur est censée être de 4 caractères. Il était une fois, la largeur de la tabulation dure était de 8 caractères, 1 retrait était de 4 blancs, 2 retraits étaient 1 onglet dur, 3 retraits étaient 1 onglet dur + 4 blancs et 4 retraits étaient 2 onglets durs.

En comparant les anciennes sources,

Liste des méthodes statiques publiques dans JDK 1.8

(1/13 postscript) Je le grep, donc collez public static String toString(int i, int radix) { public static String toUnsignedString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static String toUnsignedString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static int parseUnsignedInt(String s, int radix) public static int parseUnsignedInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException { public static Integer valueOf(int i) { public static int hashCode(int value) { public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException { public static int compare(int x, int y) { public static int compareUnsigned(int x, int y) { public static long toUnsignedLong(int x) { public static int divideUnsigned(int dividend, int divisor) { public static int remainderUnsigned(int dividend, int divisor) { public static int highestOneBit(int i) { public static int lowestOneBit(int i) { public static int numberOfLeadingZeros(int i) { public static int numberOfTrailingZeros(int i) { public static int bitCount(int i) { public static int rotateLeft(int i, int distance) { public static int rotateRight(int i, int distance) { public static int reverse(int i) { public static int signum(int i) { public static int reverseBytes(int i) { public static int sum(int a, int b) { public static int max(int a, int b) { public static int min(int a, int b) {

Liste des méthodes statiques publiques dans JDK 1.4

(1/13 postscript) Je le grep, donc collez public static String toString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException {

Recommended Posts

J'ai lu la source d'Integer
J'ai lu la source de ArrayList que j'ai lu
J'ai lu la source de Long
J'ai lu la source de Short
J'ai lu la source de Byte
J'ai lu la source de String
J'ai lu le livre de démarrage de Kotlin
DrainTo de LinkedBlockingQueue est-il sûr? J'ai suivi la source
05. J'ai essayé de supprimer la source de Spring Boot
J'ai étudié le traitement interne de Retrofit
[jour: 5] J'ai résumé les bases de Java
J'ai vérifié la partie de java.net.URL # getPath
J'ai compris les bases de la saisie de caractères
J'ai comparé les caractéristiques de Java et .NET
Je veux var_dump le contenu de l'intention
J'ai essayé d'utiliser le profileur d'IntelliJ IDEA
J'ai vérifié le nombre de taxis avec Ruby
Essayez Progate Free Edition [Java I]
[Java] Comment obtenir l'URL de la source de transition
J'ai examiné le cycle de vie de l'extension de JUnit Jupiter
Le monde de Clara-Rules (2)
J'ai essayé d'utiliser la fonction Server Push de Servlet 4.0
J'ai lu le code lisible, alors prends note
J'étais accro au record du modèle associé
J'ai vu la liste du développement Android collectivement
[Java] Informations entières des caractères du fichier texte acquises par la méthode read ()
Jugement du calendrier
J'ai essayé le nouveau profileur de fonctionnalités d'IntelliJ IDEA 2019.2.
Le monde de Clara-Rules (4)
Je veux connaître la réponse de l'application Janken
Traitement d'image: structure de base de l'image lue par le programme
Je souhaite afficher le nom de l'affiche du commentaire
J'ai résumé le format d'affichage de la réponse JSON de Rails
Le monde de Clara-Rules (1)
Le monde de Clara-Rules (3)
Lire la source Java HashMap
J'ai lu le "Guide pratique orienté objet", donc un mémorandum
Source des objets cellulaires
Relisez le guide des rails (vue d'ensemble du contrôleur d'action)
[Java] Lors de l'écriture du source ... Mémorandum ①
J'ai écrit un diagramme de séquence de l'exemple j.u.c.Flow
Le monde de Clara-Rules (5)
J'ai résumé les types et les bases des exceptions Java
L'idée du tri rapide
Je suis parfaitement conscient de la commodité de graphql-code-generator partie 2
Je ne peux pas sortir de l'écran de la console Rails db
Je veux retourner la position de défilement de UITableView!
L'idée de jQuery
J'ai créé le côté serveur du jeu de cartes en ligne ①
Je n'ai pas vraiment compris le comportement de Java Scanner et .nextLine ()
J'ai jeté un coup d'œil à l'intérieur du Java HashMap
J'ai essayé de résumer les bases de kotlin et java
[Android] Quittez l'activité de la source de transition au moment de la transition d'écran