[JAVA] Ich habe die Quelle von Integer gelesen

Irgendwie habe ich beschlossen, auch die JDK-Quelle zu lesen. Trotzdem habe ich keine Zeit, jede Zeile sorgfältig zu lesen, also habe ich sie kurz gelesen und diesen Code gefunden. Da das letzte Mal ich habe die Quelle von Short gelesen war, wird das nächste Integer sein.

Ganzzahlige Klasse

Die Integer-Klasse ist eine Wrapper-Klasse für den primitiven Typ int. Erstens Felder und Konstruktoren. Nun, es ist eine Quelle, die sich jeder vorstellen kann.

Integer.java


    private final int value;

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

IntegerCache-Klasse

Tatsächlich gibt es eine IntegerCache-Klasse, die in Javadoc nicht angezeigt wird.

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() {}
    }

Byte, Short kam und zog sich um. Da diese innere Klasse privat ist, können Sie normalerweise nicht lesen, was im Javadoc-Kommentar geschrieben steht. Es scheint, dass Sie die Obergrenze von 127 mit der Startoption -XX: AutoBoxCacheMax = size erhöhen können. Laut Numeric Cache wurde es aus JDK 1.6 hinzugefügt.

Lassen Sie uns die Quelle von JDK 1.5 überprüfen.

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, es ist erfrischend. Wie Byte und Short war es von -128 bis 127. Obwohl es sich um IntegerCache handelt, wird es von valueOf wie Byte und Short referenziert.

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

Vergleiche mit dem Vergleichsoperator ==

Vergleichen Sie wie bei Short die Instanzen mit 127 und 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);
	}

Wenn du rennst ...

$ java Main
true
false

$ java -XX:AutoBoxCacheMax=127 Main
true
false

$ java -XX:AutoBoxCacheMax=128 Main
true
true

Startoption -XX: AutoBoxCacheMax funktioniert.

Hacker's Delight-Quelle

In dem ins Japanische übersetzten Javadoc heißt es: "Hinweise zur Implementierung: Die Implementierung der" Bit Twiddling "-Methode (höchstes OneBit und numberOfTrailingZeros) ist" Hacker's Delight "(Addison Wesley, 2002) von Henry S. Warren, Jr. ) Es basiert auf. "ist was es liest. Da es aus JDK 1.5 stammt, wissen es wahrscheinlich viele von Ihnen, aber lassen Sie uns die Quelle nach der "HD" -String durchsuchen.

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 fühlt sich ein wenig an, wenn Sie sich [Algorithmus zum Zählen / Suchen von Bits] ansehen (http://www.nminoru.jp/~nminoru/programming/bitcount.html). Es scheint viel schneller zu sein, als selbst zu schleifen und zu zählen. Wann benutzt du das Problem ... highOneBit löste das Problem und ich hatte die Möglichkeit, es zu nutzen. → Weihnachtswettbewerb 2016 / A --Array Sum

In JDK 1.8 hinzugefügte Methoden

Es gibt ziemlich viele, also habe ich nur drei aufgenommen.

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

Ich brauche es nicht wirklich. Wenn Sie es trotzdem machen wollen, sollten Sie eine int-Version von Math.pow () machen. (1/13 Nachschrift) Nun, wenn es sich um eine Summe handelt, wenn es sich um eine Methode handelt, die beispielsweise das Überspringen einer Ausnahme beim Überlaufen entwickelt hat, ist sie immer noch wertvoll, aber was ist mit einer Methode, die nur a + b zurückgibt? Und da es sich um eine Integer-Klasse handelt, kommen nicht statische Methoden wie Integer add (Integer other) gut zur Geltung ... (1/13 postscript) @see java.util.function.BinaryOperator ist im javadoc-Kommentar geschrieben, aber hat es Sinn gemacht?

parseUnsignedInt-Methode

(1/13 Nachschrift) Ich habe es leicht übersprungen, aber ich habe es hinzugefügt, indem ich Long.parseUnsignedLong angesehen habe.

Ab JDK 1.8 wurde parseUnsignedInt hinzugefügt. Ist Java Int nicht signiert? Was bedeutet es, es ohne Vorzeichen zu analysieren?

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

Ich fragte mich, ob ich 0xffff_ffff_0000_0000L schreiben könnte, aber wenn es nur ein Wert von weniger als 32 Bit wäre, würde ich ihn mit int umwandeln. Mit anderen Worten, selbst wenn das Codebit gesetzt ist, wird es als int umgewandelt, so dass es negativ ist. Es analysiert unsigniert, kann aber negativ sein. Es ist eine großartige Spezifikation.

Lass es uns versuchen.

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

Wenn du rennst ...

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)

Das Ergebnis ist wie erwartet, aber sind Sie glücklich? Dies. Wenn Sie 32 Bit voll verwenden möchten, können Sie long verwenden.

Schließlich

Die in JDK 1.8 hinzugefügten Methoden enthalten parseUnsignedInt, aber ich glaube, dass es viele statische Methoden gibt. (1/13 Nachschrift) In JDK 1.8 gab es 37 öffentliche statische Methoden. Ich denke, es wäre besser, es in die IntegerUtil-Klasse zu unterteilen, wenn es so etwas gibt. Übrigens war es 13 in JDK 1.4. Es war einmal, ich dachte, es wäre eine einfachere Klasse.

Plötzlich bemerkte ich, dass die Breite der harten Lasche 4 Zeichen betragen soll. Es war einmal, dass die Breite der harten Lasche 8 Zeichen betrug, 1 Einzug 4 Leerzeichen, 2 Einrückungen 1 harte Lasche, 3 Einrückungen 1 harte Lasche + 4 Leerzeichen und 4 Einrückungen 2 harte Laschen waren.

Vergleich der alten Quellen, --JDK 1.4 Sun Microsystems Hard Tab 8 Zeichen --JDK 1.5 Sun Microsystems Hard Tab 8 Zeichen

Liste der öffentlichen statischen Methoden in JDK 1.8

(1/13 Nachschrift) Ich grep es, also füge es ein 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 der öffentlichen statischen Methoden in JDK 1.4

(1/13 Nachschrift) Ich grep es, also füge es ein 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

Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Long gelesen
Ich habe die Quelle von Short gelesen
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
Ich habe das Kotlin-Startbuch gelesen
Ist drainTo von LinkedBlockingQueue sicher? Ich bin der Quelle gefolgt
05. Ich habe versucht, die Quelle von Spring Boot zu löschen
Ich habe die interne Verarbeitung von Retrofit untersucht
[Tag: 5] Ich habe die Grundlagen von Java zusammengefasst
Ich habe den Teil von java.net.URL # getPath überprüft
Ich habe die Grundlagen der Zeicheneingabe verstanden
Ich habe die Eigenschaften von Java und .NET verglichen
Ich möchte den Inhalt der Absicht var_dump
Ich habe versucht, den Profiler von IntelliJ IDEA zu verwenden
Ich habe die Anzahl der Taxis mit Ruby überprüft
Probieren Sie Progate Free Edition [Java I]
[Java] So erhalten Sie die URL der Übergangsquelle
Ich habe den Lebenszyklus der Erweiterung von JUnit Jupiter untersucht
Die Welt der Clara-Regeln (2)
Ich habe versucht, die Server-Push-Funktion von Servlet 4.0 zu verwenden
Ich habe den lesbaren Code gelesen, machen Sie sich also eine Notiz
Ich war süchtig nach der Aufzeichnung des zugehörigen Modells
Ich habe die Listenansicht der Android-Entwicklung gemeinsam gesehen
[Java] Ganzzahlige Informationen von Zeichen in der Textdatei, die mit der Methode read () erfasst wurden
Beurteilung des Kalenders
Ich habe den neuen Feature-Profiler von IntelliJ IDEA 2019.2 ausprobiert.
Die Welt der Clara-Regeln (4)
Ich möchte die Antwort der Janken-App wissen
Bildverarbeitung: Grundstruktur des vom Programm gelesenen Bildes
Ich möchte den Namen des Posters des Kommentars anzeigen
Ich habe das Anzeigeformat der JSON-Antwort von Rails zusammengefasst
Die Welt der Clara-Regeln (1)
Die Welt der Clara-Regeln (3)
Lesen Sie die Java HashMap-Quelle
Ich habe den "Object-Oriented Practice Guide" gelesen, also ein Memorandum
Quelle zellulärer Objekte
Lesen Sie das Rails-Handbuch erneut (Übersicht über Action Controller).
[Java] Beim Schreiben der Quelle ... Memorandum ①
Ich habe ein Sequenzdiagramm des j.u.c.Flow-Beispiels geschrieben
Die Welt der Clara-Regeln (5)
Ich habe die Typen und Grundlagen von Java-Ausnahmen zusammengefasst
Die Idee der schnellen Sortierung
Ich bin mir der Bequemlichkeit des Graphql-Code-Generators Teil 2 sehr bewusst
Ich kann den Bildschirm der Rails-Datenbankkonsole nicht verlassen
Ich möchte die Bildlaufposition von UITableView zurückgeben!
Die Idee von jQuery
Ich habe die Serverseite des Online-Kartenspiels gemacht made
Ich habe das Verhalten von Java Scanner und .nextLine () nicht wirklich verstanden.
Ich habe einen Blick in die Java HashMap geworfen
Ich habe versucht, die Grundlagen von Kotlin und Java zusammenzufassen
[Android] Beenden Sie die Aktivität der Übergangsquelle zum Zeitpunkt des Bildschirmübergangs