Certaines des raisons ont déjà été évoquées. Par exemple, le fait que "... (Presque) Toutes les opérations sur octet, short promouvra ces primitives en int" . Cependant, la prochaine question évidente serait: POURQUOI ces types sont-ils promus int
?
Donc, pour aller un peu plus loin: la réponse peut simplement être liée au jeu d'instructions de la machine virtuelle Java. Comme résumé dans le tableau de la spécification de la machine virtuelle Java , toutes les opérations arithmétiques intégrales, telles que l'ajout, la division et autres, ne sont disponibles que pour le type int
et le type long
, et non pour les types plus petits.
(Un aparté: les types plus petits ( byte
et short
) sont essentiellement destinés uniquement aux tableaux . Un tableau comme new byte[1000]
prendra 1000 octets, et un tableau comme new int[1000]
prendra 4000 octets)
Maintenant, bien sûr, on pourrait dire que "... la prochaine question évidente serait: POURQUOI ces instructions sont-elles proposées uniquement pour int
(et long
)?" .
Une raison est mentionnée dans la spécification JVM mentionnée ci-dessus:
Si chaque instruction saisie prenait en charge tous les types de données d'exécution de la machine virtuelle Java, il y aurait plus d'instructions que ce qui pourrait être représenté dans un octet
De plus, la machine virtuelle Java peut être considérée comme une abstraction d'un processeur réel. Et l'introduction d'une unité logique arithmétique dédiée pour les types plus petits ne vaudrait pas la peine: elle aurait besoin de transistors supplémentaires, mais elle ne pourrait toujours exécuter qu'une seule addition en un cycle d'horloge. L'architecture dominante lors de la conception de la JVM était de 32 bits, juste pour un 32 bits int
. (Les opérations qui impliquent une long
valeur de 64 bits sont implémentées comme cas particulier).
(Remarque: le dernier paragraphe est un peu simplifié, considérant la vectorisation possible, etc., mais devrait donner une idée de base sans plonger trop profondément dans les sujets de conception de processeur)
EDIT: Un petit addendum, se concentrant sur l'exemple de la question, mais dans un sens plus général: On pourrait également se demander s'il ne serait pas avantageux de stocker des champs en utilisant les types plus petits. Par exemple, on pourrait penser que la mémoire pourrait être sauvegardée en stockant Calendar.DAY_OF_WEEK
sous forme de fichier byte
. Mais ici, le format de fichier de classe Java entre en jeu: tous les champs d'un fichier de classe occupent au moins un "emplacement", qui a la taille d'un int
(32 bits). (Les champs "larges", double
et long
, occupent deux emplacements). Donc, déclarer explicitement un champ comme short
ou byte
ne sauverait pas non plus de mémoire.
int
. Si vous avez une référence à une autre implémentation, je mettrais à jour la réponse et j'insérerais le lien en conséquence.(Presque) Toutes les opérations sur
byte
,short
les promouvrontint
, par exemple, vous ne pouvez pas écrire:Les arithmétiques sont plus faciles et simples lors de l'utilisation
int
, pas besoin de lancer.En termes d'espace, cela fait très peu de différence.
byte
etshort
compliquerait les choses, je ne pense pas que cette micro-optimisation en vaille la peine puisque nous parlons d'un nombre fixe de variables.byte
est pertinent et utile lorsque vous programmez pour des appareils intégrés ou que vous traitez des fichiers / réseaux. De plus, ces primitives sont limitées, et si les calculs pouvaient dépasser leurs limites à l'avenir? Essayez de penser à une extension pour laCalendar
classe qui pourrait faire évoluer de plus grands nombres.A noter également que dans les processeurs 64 bits, les habitants seront enregistrés dans les registres et ne pas utiliser de ressources, donc l' utilisation
int
,short
et d' autres primitives ne fera aucune différence. De plus, de nombreuses implémentations Java alignent les variables * (et les objets).*
byte
etshort
occupent le même espace queint
s'il s'agissait de variables locales , de variables de classe ou même de variables d' instance . Pourquoi? Parce que dans (la plupart des) systèmes informatiques, les adresses des variables sont alignées , donc par exemple si vous utilisez un seul octet, vous vous retrouverez en fait avec deux octets - un pour la variable elle-même et un autre pour le remplissage.D'un autre côté, dans les tableaux,
byte
prenez 1 octet,short
prenez 2 octets etint
prenez quatre octets, car dans les tableaux, seuls le début et peut-être la fin doivent être alignés. Cela fera une différence au cas où vous voudriez utiliser, par exempleSystem.arraycopy()
, alors vous remarquerez vraiment une différence de performances.la source
Parce que les opérations arithmétiques sont plus faciles lors de l'utilisation d'entiers par rapport aux courts-circuits. Supposons que les constantes ont effectivement été modélisées par des
short
valeurs. Ensuite, vous devrez utiliser l'API de cette manière:Remarquez le casting explicite. Les valeurs courtes sont implicitement promues en
int
valeurs lorsqu'elles sont utilisées dans des opérations arithmétiques. (Sur la pile d'opérandes, les courts-circuits sont même exprimés en entiers.) Ce serait assez difficile à utiliser, c'est pourquoi lesint
valeurs sont souvent préférées pour les constantes.Par rapport à cela, le gain d'efficacité de stockage est minime car il n'existe qu'un nombre fixe de telles constantes. On parle de 40 constantes. Changer leur stockage de
int
àshort
vous protégerait40 * 16 bit = 80 byte
. Voir cette réponse pour plus de références.la source
Si vous utilisiez la philosophie selon laquelle les constantes intégrales sont stockées dans le plus petit type dans lequel elles s'inscrivent, alors Java aurait un problème sérieux: chaque fois que les programmeurs écrivent du code en utilisant des constantes intégrales, ils doivent faire très attention à leur code pour vérifier si le type de les constantes comptent, et si c'est le cas, recherchez le type dans la documentation et / ou effectuez les conversions de type nécessaires.
Alors maintenant que nous avons décrit un problème grave, quels avantages pourriez-vous espérer obtenir avec cette philosophie? Je ne serais pas surpris si le seul effet observable à l'exécution de ce changement serait le type que vous obtenez lorsque vous regardez la constante par réflexion. (et, bien sûr, quelles que soient les erreurs introduites par des programmeurs paresseux / involontaires ne tenant pas correctement compte des types de constantes)
Peser le pour et le contre est très simple: c'est une mauvaise philosophie.
la source
La complexité de conception d'une machine virtuelle est fonction du nombre de types d'opérations qu'elle peut effectuer. Il est plus facile d'avoir quatre implémentations d'une instruction comme "multiplier" - une pour chaque entier 32 bits, entier 64 bits, virgule flottante 32 bits et virgule flottante 64 bits - que d'avoir, en plus à ce qui précède, des versions pour les types numériques plus petits également. Une question de conception plus intéressante est de savoir pourquoi il devrait y avoir quatre types, plutôt que moins (effectuer tous les calculs d'entiers avec des entiers 64 bits et / ou faire tous les calculs à virgule flottante avec des valeurs à virgule flottante 64 bits). La raison de l'utilisation d'entiers 32 bits est que Java était censé fonctionner sur de nombreuses plates-formes où les types 32 bits pourraient être utilisés aussi rapidement que les types 16 bits ou 8 bits, mais les opérations sur les types 64 bits seraient notables. Ralentissez.ayant uniquement des types 32 bits.
En ce qui concerne les calculs en virgule flottante sur des valeurs 32 bits, les avantages sont un peu moins évidents. Il existe des plates-formes où un calcul comme
float a=b+c+d;
pourrait être effectuée plus rapidement en convertissant tous les opérandes en un type de plus haute précision, en les ajoutant, puis en reconvertissant le résultat en un nombre à virgule flottante de 32 bits pour le stockage. Il existe d'autres plates-formes où il serait plus efficace d'effectuer tous les calculs en utilisant des valeurs à virgule flottante 32 bits. Les créateurs de Java ont décidé que toutes les plates-formes devraient être obligées de faire les choses de la même manière, et qu'ils devraient favoriser les plates-formes matérielles pour lesquelles les calculs en virgule flottante 32 bits sont plus rapides que les plus longs, même si ce PC gravement dégradé à la fois la vitesse et la précision des calculs en virgule flottante sur un PC classique, ainsi que sur de nombreuses machines sans unités à virgule flottante. Notez, btw, qu'en fonction des valeurs de b, c et d, utiliser des calculs intermédiaires de plus haute précision lors du calcul d'expressions comme celles mentionnées ci-dessusfloat a=b+c+d;
produira parfois des résultats nettement plus précis que ceux obtenus avec tous les opérandes intermédiaires calculés avecfloat
précision, mais produira parfois une valeur un tout petit peu moins précise. Dans tous les cas, Sun a décidé que tout devait être fait de la même manière et a opté pour l'utilisation defloat
valeurs de précision minimale .Notez que les principaux avantages des types de données plus petits deviennent évidents lorsqu'un grand nombre d'entre eux sont stockés ensemble dans un tableau; même s'il n'y avait aucun avantage à avoir des variables individuelles de types inférieurs à 64 bits, il vaut la peine d'avoir des tableaux qui peuvent stocker des valeurs plus petites de manière plus compacte; avoir une variable locale être a
byte
plutôt que anlong
économise sept octets; avoir un tableau de 1000000 de nombres contient chaque nombre comme unbyte
plutôt qu'unlong
ondes 7 000 000 octets. Étant donné que chaque type de tableau n'a besoin de prendre en charge que quelques opérations (notamment lire un élément, stocker un élément, copier une plage d'éléments dans un tableau ou copier une plage d'éléments d'un tableau à un autre), la complexité supplémentaire d'avoir plus les types de tableaux n'est pas aussi grave que la complexité d'avoir plus de types de valeurs numériques discrètes directement utilisables.la source
En fait, il y aurait un petit avantage. Si tu as un
puis sur une JVM typique, il a besoin d'autant d'espace qu'une classe contenant un seul
int
. La consommation de mémoire est arrondie à un multiple suivant de 8 ou 16 octets (IIRC, c'est configurable), de sorte que les cas où il y a une réelle sauvegarde sont plutôt rares.Cette classe serait légèrement plus facile à utiliser si les
Calendar
méthodes correspondantes renvoyaient un fichierbyte
. Mais il n'y a pas de tellesCalendar
méthodes, seulementget(int)
qui doit renvoyer un àint
cause d'autres champs. Chaque opération sur des types plus petits favoriseint
, donc vous avez besoin de beaucoup de casting.Très probablement, vous abandonnerez et passerez à un
int
ou écrivez des setters commeAlors le type de
DAY_OF_WEEK
n'importe pas, de toute façon.la source