[JAVA] J'ai lu la source de Short

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, c'était j'ai lu la source de Byte, donc le prochain est Short.

Cours court

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

Short.java


    private final short value;

    public Short(short value) {
        this.value = value;
    }

Classe ShortCache

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

Short.java


    private static class ShortCache {
        private ShortCache(){}

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

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

N'est-ce pas une copie de l'explication de la classe Byte jusqu'à présent? !! !! Pour le moment, la différence avec la classe Byte est qu'elle met en cache les instances de -128 à 127. Il semble que je n'ai pas créé d'instance de -32768 à 32767 car elle est courte.

C'est un cache de ShortCache, mais il est référencé par valueOf.

Short.java


    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }

Comparer avec l'opérateur de comparaison ==

Pour le moment, c'est la même chose que Byte, et si vous faites new Short (), ce sera une autre instance. Short.valueOf () et autoboxing sont probablement les mêmes.

Main.java


	public static void main(String[] args) {
		short s00 = 127;
		Short s01 = Short.valueOf(s00);
		Short s02 = s00;
		System.out.println(s01 == s02);
		short s10 = 128;
		Short s11 = Short.valueOf(s10);
		Short s12 = s10;
		System.out.println(s11 == s12);
	}

Le résultat est ···

true
false

Eh bien, c'est naturel. Dans valueOf (), 127 ou moins utilise le cache, mais 128 ou plus est nouveau Short (). Pour le moment, la même instance sera comprise entre -127 et 128, mais il vaut mieux éviter de trop comparer les valeurs de référence.

Mais j'utilise l'opérateur de comparaison ==

Cependant, il semble qu'il y ait des occasions où l'opérateur de comparaison == est utilisé.

Main.java


	public static void main(String[] args) {
		short s11 = 128;
		short s12 = 128;
		Short s21 = s11;
		Short s22 = s12;
		System.out.println(s11 == s12);
		System.out.println(s11 == s22);
		System.out.println(s21 == s12);
		System.out.println(s21 == s22);
	}

Le premier est une primitive, le second est une primitive et un wrapper, et le quatrième est une comparaison de wrapper. En fait, les deuxième et troisième déballent automatiquement. Par conséquent, le résultat est ...

true
true
true
false

C'est assez difficile. Le résultat change selon que le s dans le nom du modèle est inférieur ou supérieur, ce qui est un niveau fou pour moi personnellement. De plus, comme je l'ai écrit plus tôt, -127 à 128 sera vrai pour tous les 4èmes wrappers. Comment puis-je expliquer cela à quelqu'un qui ressemble à Java pour la première fois en un mois et le comprendre correctement à 100%?

Il était une fois quelque chose appelé JDK 1.4

Il existe une version appelée JDK 1.4, et pour le moment, même le JDK 1.8 actuel peut être compilé à ce niveau 1.4.

$ javac -source 1.4 -target 1.4 Main.java
avertissement: [options]Chemin de classe Bootstrap-source 1.Non défini avec 4
avertissement: [options]Valeur source 1.4 est obsolète et sera supprimé dans une prochaine version
avertissement: [options]Valeur cible 1.4 est obsolète et sera supprimé dans une prochaine version
avertissement: [options] 廃止されたオプションについてのavertissementを表示しないようにするには、-Xlint:Utilisez l'option.
Main.java:15:Erreur:Type incompatible:Impossible de convertir court en court:
                Short s21 = s11;
                            ^
Main.java:16:Erreur:Type incompatible:Impossible de convertir court en court:
                Short s22 = s12;
                            ^
Main.java:18:Erreur:Opérateur binaire'=='Le type d'opérande de n'est pas valide
                System.out.println(s11 == s22);
                                       ^
Premier type: short
Deuxième type: Short
Main.java:19:Erreur:Opérateur binaire'=='Le type d'opérande de n'est pas valide
                System.out.println(s21 == s12);
                                       ^
Premier type: Short
Deuxième type: short
4 erreurs
4 avertissements

En fait, JDK 1.4 lui-même est également inclus,

$ javac Main.java
Main.java:15:Type incompatible
Valeur détectée: short
Valeur attendue: java.lang.Short
                Short s21 = s11;
                            ^
Main.java:16:Type incompatible
Valeur détectée: short
Valeur attendue: java.lang.Short
                Short s22 = s12;
                            ^
Main.java:18:opérateur==C'est court,java.lang.Ne s'applique pas à Short.
                System.out.println(s11 == s22);
                                       ^
Main.java:19:opérateur==Est java.lang.Short,Ne s'applique pas à court.
                System.out.println(s21 == s12);
                                       ^
4 erreurs

Le message d'erreur est légèrement différent. La raison de l'erreur est que l'autoboxing / unboxing a été ajouté depuis JDK 1.5. Alors, quel genre de source avez-vous écrit avant JDK 1.4?

Main.java


	public static void main(String[] args) {
		short s11 = 128;
		short s12 = 128;
		Short s21 = Short.valueOf(s11);
		Short s22 = Short.valueOf(s12);
		System.out.println(s11 == s12);
		System.out.println(s11 == s22.shortValue());
		System.out.println(s21.shortValue() == s12);
		System.out.println(s21 == s22);
	}

Il semble que, en fait,

Main.java


	public static void main(String[] args) {
		short s11 = 128;
		short s12 = 128;
		Short s21 = new Short(s11);
		Short s22 = new Short(s12);
		System.out.println(s11 == s12);
		System.out.println(s11 == s22.shortValue());
		System.out.println(s21.shortValue() == s12);
		System.out.println(s21 == s22);
	}

Qu'Est-ce que c'est? Short.valueOf (short) est une méthode ajoutée à partir du JDK 1.5. Si je compile avec javac -source 1.4 -target 1.4 avec JDK 1.8, je peux le compiler.

Donc, je pense qu'il aurait été plus facile à comprendre s'il n'y avait pas de déballage automatique.

méthode de comparaison

Il existe une méthode appelée compare, mais organisons-la comme Byte, Short, Integer, Long pour une compréhension facile.

Byte.java


    public static int compare(byte x, byte y) {
        return x - y;
    }

Short.java


    public static int compare(short x, short y) {
        return x - y;
    }

Integer.java


    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

Long.java


    public static int compare(long x, long y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

Pouvez-vous voir la différence? Même si j'étais un int dans ma propre classe, je l'ai sauté et j'ai écrit return x --y;. Cela fonctionne en quelque sorte, mais dans un cas extrême, il déborde à x = 0x7FFFFFFF; y = -1. C'est pourquoi c'est un bug.

Ainsi, Byte et Short renvoient x --y; car le résultat se situe dans la plage de int.

Méthode toUnsignedInt, méthode toUnsignedLong

C'est le point culminant d'aujourd'hui. Je veux dire, y avait-il quelque chose comme ça? Si vous pensez que oui, il est ajouté dans JDK 1.8.

Short.java


    public static int toUnsignedInt(short x) {
        return ((int) x) & 0xffff;
    }

    public static long toUnsignedLong(short x) {
        return ((long) x) & 0xffffL;
    }

Ce qu'il faut faire est de convertir de short signé en short non signé, mais comme il ne peut pas être exprimé par short, il est renvoyé par int ou long. Depuis que je suis arrivé à Java depuis le langage C, j'ai tendance à penser que je devrais l'écrire moi-même, mais je pense qu'il vaut mieux utiliser celui qui est préparé, comme une macro en langage C. Je vais.

finalement

Eh bien, généralement, je n'utilise pas Short, j'utilise Integer.

Recommended Posts

J'ai lu la source de Short
J'ai lu la source de ArrayList que j'ai lu
J'ai lu la source d'Integer
J'ai lu la source de Long
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
J'ai essayé de réduire la capacité de Spring Boot
Jugement du calendrier
J'ai essayé le nouveau profileur de fonctionnalités d'IntelliJ IDEA 2019.2.
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)
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
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
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
Je souhaite modifier le paramètre de sortie du journal de UtilLoggingJdbcLogger
J'ai essayé JAX-RS et pris note de la procédure
Spécifiez le code de caractère de la source lors de la construction avec Maven