Le xyz littéral de type int est hors de portée

89

Je travaille actuellement avec des types de données en Java, et si j'ai bien compris le type long accepte une valeur comprise entre -9 223 372 036 854 775 808 et +9 223 372 036 854 775 807. Maintenant, comme vous pouvez le voir ci-dessous, j'ai créé une longvariable appeléetestLong , bien que lorsque j'insère 9223372036854775807 comme valeur, j'obtiens une erreur indiquant:

Le littéral 9223372036854775807 du type int est hors limites.

Je ne sais pas pourquoi il fait référence au long type de données en tant que fichier int.

Quelqu'un a des idées?

Code:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Mathew Donnan
la source
Au fait: quel compilateur utilisez-vous? Eclipse et le compilateur Sun JDK donnent des messages d'erreur différents (à mon avis mieux) pour ce problème.
Joachim Sauer

Réponses:

195

Ajoutez une majuscule Là la fin:

long value = 9223372036854775807L;

Sinon, le compilateur essaiera d'analyser le littéral comme un int, d'où le message d'erreur

Lukas Eder
la source
4
C'est dans les spécifications du langage Java. Retrouvez le texte intégral ici
Lukas Eder
@Lukas, valeur longue = 00000077029062100L; me donne la même erreur, et il est inférieur à 19 chiffres. toute Idée pourquoi il lance "Le littéral 0000007702062100L de type long est hors de portée"
Santossh Kumhar
1
@SantosshKumhar: C'est un littéral octal , qui ne peut pas contenir de chiffres 8ou 9. Supprimez les zéros de tête.
Lukas Eder
49

Je ne sais pas pourquoi il fait référence au type de données long comme un int

Ce n'est pas. Vous devez apprendre à faire confiance aux messages du compilateur (surtout lorsqu'ils proviennent de compilateurs sains et modernes et non d'anciens compilateurs C / C ++). Bien que la langue qu'ils parlent soit parfois difficile à déchiffrer, ils ne vous mentent généralement pas.

Regardons à nouveau:

Le littéral de int 9223372036854775807 est hors de portée.

Notez qu'il ne mentionne nulle part votre variable testLongou le type long, donc ce n'est pas de l'initialisation. Le problème semble survenir à un autre moment.

Examinons maintenant certaines parties du message:

  • int nous dit qu'il veut traiter quelque chose comme un int valeur (ce qui n'est pas ce que vous vouliez!)
  • "hors de portée" est assez clair: quelque chose n'est pas dans la plage attendue (probablement celle de int )
  • "Le littéral": maintenant c'est intéressant: qu'est-ce qu'un littéral?

Je vais laisser la liste confortable pour parler des littéraux pendant un moment: les littéraux sont des endroits où vous avez une certaine valeur dans votre code. Il y a des Stringlittéraux, des intlittéraux, des classlittéraux, etc. Chaque fois que vous mentionnez une valeur explicitement dans votre code, c'est un littéral.

Donc, ce n'est pas vraiment vous harceler à propos de la déclaration de variable, mais le nombre lui-même, la valeur est ce qui vous harcèle.

Vous pouvez facilement le vérifier en utilisant le même littéral dans un contexte où a longet an intsont également acceptables:

System.out.println(9223372036854775807);

PrintStream.printlnpeut prendre unint ou unlong (ou à peu près n'importe quoi d'autre). Donc, ce code devrait être correct, non?

Non. Peut-être que ça devrait l' être, mais selon les règles, ce n'est pas bien.

Le problème est que "certains chiffres" est défini comme un intlittéral et doit donc être dans la plage définie par int.

Si vous voulez écrire un longlittéral, vous devez le rendre explicite en ajoutant L(ou en minuscules l, mais je vous suggère fortement d' utiliser toujours la variante majuscule, car c'est beaucoup plus facile à lire et plus difficile à confondre avec a 1).

Notez qu'un problème similaire se produit avec float(postfix F/ f) et double(postfix D/ d).

Note latérale: vous vous rendrez compte qu'il n'y a pas de byteou shortlittéraux et que vous pouvez toujours attribuer des valeurs (généralement des intlittéraux) à byteet des shortvariables: c'est possible grâce aux règles spéciales du § 5.2 sur Assignment Converson : elles permettent l'affectation d'expressions constantes d'un type plus grand à byte, short, charou int si les valeurs se situent dans les types varient.

Joachim Sauer
la source
3
D'où prenez-vous le temps ;-)
Lukas Eder
3
@Lukas: J'écris parfois de telles réponses dans l'espoir de ne pas avoir à en écrire 300 plus courtes ;-) Aussi: aider à interpréter le message d'erreur (espérons-le) signifie moins de questions "qu'est-ce que ce message d'erreur signifie".
Joachim Sauer
votre réponse est très bonne ... sans aucun doute, c'est pourquoi votez, mais veuillez la modifier et en haut (début de votre réponse), écrivez simplement en 1 ligne la solution exacte du problème, puis en dessous de votre explication. Parce que beaucoup de gens recherchent une solution rapide plutôt qu'une explication profonde
Shirish Herwade
4
Ils sont libres de regarder d'autres secondes réponses (la plus votée donne même la solution rapide). Je pense qu'éduquer les gens sur la façon d'analyser et de comprendre les messages d'erreur est plus utile à long terme que de le faire simplement pour eux. "Donnez un poisson à un homme ..." et tout ça.
Joachim Sauer
Merci pour la note latérale.
Venkatesh Goud
17

Essayez de faire 9223372036854775807L. Le Là la fin indique à Java qu'il 9223372036854775807s'agit d'un fichier long.

jontro
la source
0

J'ai eu ce problème dans le passé et je l'ai résolu en écrivant la valeur sous forme scientifique. par exemple:

double val = 9e300;

la source
-2
long ak = 34778754226788444L/l;

Les deux utilisent mais à la fois un seul utilise L majuscule ou l minuscule.

Pourquoi utiliser L / l? Parce que long fait partie du type de données intégral.

Akkushwaha
la source