Spécification du numéro L de Java (long)

95

Il semble que lorsque vous tapez un nombre en Java, le compilateur le lit automatiquement comme un entier, c'est pourquoi lorsque vous tapez (long) 6000000000(pas dans la plage d'entiers), il se plaindra que ce 6000000000n'est pas un entier. Pour corriger cela, j'ai dû préciser 6000000000L. Je viens d'apprendre cette spécification.

Existe-t-il d'autres spécifications numériques comme pour court, octet, flottant, double? Il semble que ce serait bien d'avoir parce que (je suppose) si vous pouviez spécifier le nombre que vous saisissez est un court alors java n'aurait pas à le lancer - c'est une hypothèse, corrigez-moi si je me trompe . Normalement, je chercherais moi-même cette question, mais je ne sais pas comment s'appelle même ce type de spécification de nombre.

jbu
la source

Réponses:

174

Il existe des suffixes spécifiques pour long(par exemple 39832L), float(par exemple 2.4f) et double(par exemple-7.832d ).

S'il n'y a pas de suffixe et qu'il s'agit d'un type intégral (par exemple 5623), il est supposé être un int. S'il ne s'agit pas d'un type intégral (par exemple 3.14159), il est supposé être undouble .

Dans tous les autres cas ( byte, short,char ), vous avez besoin du casting car il n'y a pas de suffixe spécifique.

La spécification Java autorise les suffixes majuscules et minuscules, mais la version majuscule pour longs est préférée, car les majuscules Lsont moins faciles à confondre avec un chiffre1 que les minuscules l.

Voir la section 3.10 de JLS pour les détails sanglants (voir la définition de IntegerTypeSuffix).

Simon Nickerson
la source
9
Entrée tardive: supprimer les sources potentielles d'ambiguïté est toujours une bonne chose , et je ne suis pas en désaccord ... mais je crois que si vous vous trouvez dans la confusion 1avec let 0avec O(et ainsi de suite), votre priorité est de définir la police correctement (si vous le pouvez ), puis assurez-vous de ne pas manquer la touche Maj.
davidcsb
@SimonNickerson J'ai une question sur les suffixes ... Si je déclare une variable longue ou double comme: long _lo = 30;et 30Lcela ne signifie-t-il pas que ma variable sera convertie en float ? Ou dans le cas _lo = _lo + 2.77_locela sera jeté dans le flotteur bien qu'il ait été déclaré long
luigi7up
Non, les flotteurs ne sont pas impliqués ici. Dans le premier cas, 30est un intqui est automatiquement converti via une conversion élargie en un fichier long. Dans le second cas, votre déclaration est illégale. Vous auriez à lancer explicitement le côté droit à long, par exemple_lo = (long) (_lo + 2.77)
Simon Nickerson
4
@DavidCesarino changer la police corrige l'ambiguïté pour vous - dans cet éditeur particulier où vous l'avez réglé correctement. Changer l en L corrige l'ambiguïté pour tous ceux qui pourraient lire votre code, y compris vous-même, lorsque vous lisez le code dans un autre éditeur, IDE, en regardant la source sur le Web (outils de révision, référentiels, etc.). IMHO la priorité est de ne pas manquer la touche Shift. Btw. quelle police recommandez-vous? J'aime monospace et c'est la valeur par défaut dans presque tous les éditeurs, CLI, etc. que j'ai vus et dans cette police let 1( 0et Oresp.) Sont assez similaires.
dingalapadum
1
@dingalapadum Comme je l'ai dit, vous avez raison. Supprimer les sources d'ambiguïté est définitivement une bonne chose à faire. Je viens de dire que vous devriez essayer de ne pas utiliser d'éditeur où vous pourriez facilement les confondre. En d'autres termes, la vieille suggestion de coder défensivement, mais pas en dépendant. Concernant la police, elle est très personnelle, mais j'utilise toujours Deja Vu Sans Mono chaque fois que je peux car 1) elle est monospace; 2) il n'y a pas d'ambiguïtés entre les personnages; et 3) J'aime ses formes, belles et gracieuses, presque comme une bonne police sans empattement lisible (d'autres bonnes polices de programmation semblent trop "métalliques" à mon humble avis).
davidcsb
13

J'espère qu'une légère tangente ne vous dérangera pas, mais j'ai pensé que cela pourrait vous intéresser de savoir qu'en plus F(pour float), D(pour double) et L(pour longtemps), une proposition a été faite d'ajouter des suffixes pour byteet short- Yet Srespectivement . Cela éliminerait le besoin de transtyper en octets lors de l'utilisation d'une syntaxe littérale pour des tableaux d'octets (ou courts). Citant l'exemple de la proposition:

AVANTAGE MAJEUR: Pourquoi la plateforme est-elle meilleure si la proposition est adoptée?

code grossier comme

 byte[] stuff = { 0x00, 0x7F, (byte)0x80,  (byte)0xFF};

peut être recodé comme

 byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy };

Joe Darcy supervise Project Coin pour Java 7, et son blog a été un moyen facile de suivre ces propositions.

Erickson
la source
ce serait bien ... j'ai toujours trouvé que tous les lancers sont vraiment ennuyeux
jbu
Je suppose que cela ne l'a pas fait en Java 7. Un mot pour savoir si cela en fera une future mise à jour ou Java 8?
écraser
@crush J'ai essayé de l'examiner il y a quelques mois, et pour autant que je sache, la proposition avait été abandonnée. Nous avons cependant obtenu _ dans les littéraux numériques et le 0bpréfixe pour les littéraux binaires. Cri.
erickson
Ces propositions sont probablement mises en œuvre sur kotlin au lieu de java, car oracle ne veut pas que la communauté leur dise comment travailler ... nous sommes en 2018 et toujours rien à propos de cette proposition, malheureusement
JoelBonetR
11

Par défaut, tout type de données primitif intégral (byte, short, int, long) sera traité comme type int par le compilateur java. Pour byte et short , tant que la valeur qui leur est assignée est dans leur plage, il n'y a aucun problème et aucun suffixe requis. Si la valeur attribuée à byte et short dépasse leur plage, une conversion de type explicite est requise.

Ex:

byte b = 130; // CE: range is exceeding.

pour surmonter cette coulée de type effectuer.

byte b = (byte)130; //valid, but chances of losing data is there.

En cas de type de données long, il peut accepter la valeur entière sans aucun problème. Supposons que nous attribuions comme

Long l = 2147483647; //which is max value of int

dans ce cas, aucun suffixe comme L / l n'est requis. Par défaut, la valeur 2147483647 est considérée par le compilateur java de type int. Le cast de type interne est effectué par le compilateur et int est automatiquement promu en type Long.

Long l = 2147483648; //CE: value is treated as int but out of range 

Ici, nous devons mettre le suffixe L pour traiter le littéral 2147483648 comme un type long par le compilateur java.

donc finalement

Long l = 2147483648L;// works fine.
Utpal Kumar
la source
9

Ce sont des littéraux et sont décrits dans la section 3.10 de la spécification du langage Java.

McDowell
la source
1

Il semble que ce serait bien d'avoir parce que (je suppose) si vous pouviez spécifier le nombre que vous tapez est un court alors java n'aurait pas à le lancer

Étant donné que l'analyse des littéraux se produit au moment de la compilation, cela n'a absolument aucune importance en termes de performances. La seule raison d'avoir shortetbyte suffixes serait bien est qu'il conduit à un code plus compact.

Michael Borgwardt
la source
0

Pour comprendre pourquoi il est nécessaire de faire la distinction entre intet longlittéraux, considérez:

long l = -1 >>> 1;

contre

int a = -1;
long l = a >>> 1;

Maintenant, comme vous vous en doutez, les deux fragments de code donnent la même valeur à variable l. Sans pouvoir distinguer intet longlittéralement, quelle est l'interprétation de -1 >>> 1?

-1L >>> 1 // ?

ou

(int)-1 >>> 1 // ?

Donc, même si le nombre est dans la plage commune, nous devons spécifier le type. Si la valeur par défaut changeait avec la magnitude du littéral, alors il y aurait un changement étrange dans les interprétations des expressions simplement en changeant les chiffres.

Cela ne se produit pas byte, shortet charparce qu'ils sont toujours promu avant d' effectuer des opérations arithmétiques et au niveau du bit. On peut soutenir qu'il devrait s'agir de suffixes de type entier à utiliser, par exemple, dans des expressions d'initialisation de tableau, mais ce n'est pas le cas. floatutilise le suffixe fet double d. D'autres littéraux ont des types non ambigus, avec un type spécial pour null.

Tom Hawtin - Tacle
la source
Je serais vraiment intéressé par ce que vous vouliez dire à l'époque. Dans les deux cas, j'obtiens 2147483647 et je ne comprends pas pourquoi je devrais m'attendre à autre chose.
L'incroyable
@TheincredibleJan Vous attendez à juste titre Integer.MAX_VALUE, s'il n'y avait pas moyen de distinguer entre intet longlittéraux il serait ambigu. / Je ne me souviens pas de cette question, mais j'ai quand même clarifié ma réponse.
Tom Hawtin - tackline le