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.
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;
}
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);
}
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.
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 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.
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.
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.
Eh bien, généralement, je n'utilise pas Short, j'utilise Integer.
Recommended Posts