O literal xyz do tipo int está fora do intervalo

89

Estou trabalhando com tipos de dados no momento em Java e, se entendi corretamente, o tipo longaceita um valor entre os intervalos de -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807. Agora, como você pode ver abaixo, criei uma longvariável chamada testLong, embora quando eu insiro 9223372036854775807 como o valor, receba um erro informando:

O literal 9223372036854775807 do tipo int está fora do intervalo.

Não sei por que está se referindo ao longtipo de dados como um int.

Alguém tem alguma ideia?

Código:

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
fonte
A propósito: qual compilador você está usando? Tanto o Eclipse quanto o compilador Sun JDK fornecem mensagens de erro diferentes (na minha opinião, melhores) para esse problema.
Joachim Sauer de

Respostas:

195

Adicione uma maiúscula Lao final:

long value = 9223372036854775807L;

Caso contrário, o compilador tentará analisar o literal como um int, daí a mensagem de erro

Lukas Eder
fonte
4
Está nas especificações da linguagem Java. Encontre o texto completo aqui
Lukas Eder
@Lukas, valor longo = 00000077029062100L; me dá o mesmo erro, e tem menos de 19 dígitos. qualquer ideia de por que está jogando "O literal 0000007702062100L do tipo longo está fora do intervalo"
Santossh Kumhar
1
@SantosshKumhar: Esse é um literal octal , que não pode conter dígitos 8ou 9. Remova os zeros à esquerda.
Lukas Eder
49

Não sei por que está se referindo ao tipo de dados longo como um int

Não é. Você deve aprender a confiar nas mensagens do compilador (especialmente quando são de compiladores sãos e modernos, e não de compiladores C / C ++ antigos). Embora a linguagem que eles falam possa ser difícil de decifrar às vezes, eles geralmente não estão mentindo para você.

Vamos olhar de novo:

O literal de int 9223372036854775807 está fora do intervalo.

Observe que ele não menciona sua variável testLongou o tipo em longlugar nenhum, portanto, não é sobre a inicialização. O problema parece ocorrer em algum outro ponto.

Agora vamos investigar algumas das partes da mensagem:

  • intnos diz que deseja tratar algo como um intvalor (que não é o que você queria!)
  • "fora do intervalo" é bastante claro: algo não está dentro do intervalo esperado (provavelmente de int)
  • "O literal": isso é interessante: o que é um literal?

Vou deixar a lista aconchegante para falar sobre literais por um momento: literais são lugares onde você tem algum valor em seu código. Existem Stringliterais, intliterais, classliterais e assim por diante. Cada vez que você menciona um valor explicitamente em seu código, é um literal.

Portanto, não está realmente incomodando você sobre a declaração da variável, mas o próprio número, o valor é o que está incomodando você.

Você pode verificar isso facilmente usando o mesmo literal em um contexto onde a longe an intsão igualmente aceitáveis:

System.out.println(9223372036854775807);

PrintStream.printlnpode levar umint ou umlong (ou praticamente qualquer outra coisa). Então esse código deve estar bem, certo?

Não. Bem, talvez devesse ser, mas de acordo com as regras não está bem.

O problema é que "alguns dígitos" são definidos como intliterais e, portanto, devem estar no intervalo definido por int.

Se você quer escrever um longliteral, então você deve fazer que explícita, acrescentando o L(caso ou menor l, mas eu altamente sugiro que você use sempre a variante maiúsculas, porque é muito mais fácil de ler e mais difícil de erro para um 1).

Observe que um problema semelhante ocorre com float(postfix F/ f) e double(postfix D/ d).

Nota lateral: você perceberá que não há byteou shortliterais e ainda pode atribuir valores (geralmente intliterais) a variáveis bytee short: isso é possível devido a regras especiais no § 5.2 sobre Assignment Converson : eles permitem a atribuição de expressões constantes de um tipo maior a byte, short, charou int , se os valores estão dentro dos tipos variam.

Joachim Sauer
fonte
3
De onde você tira o tempo ;-)
Lukas Eder de
3
@Lukas: Eu ocasionalmente escrevo essas respostas na esperança de não ter que escrever 300 respostas mais curtas para isso ;-) Além disso: ajudar a interpretar a mensagem de erro (espero) significa menos perguntas do tipo "o que essa mensagem de erro significa".
Joachim Sauer
sua resposta é muito boa ... sem dúvida, por isso vote positivamente, mas por favor edite-a e no início (início de sua resposta), escreva em 1 linha a solução exata para o problema, e abaixo sua explicação. Porque muitas pessoas procuram uma solução rápida em vez de uma explicação profunda
Shirish Herwade
4
Eles são livres para olhar para outras segundas respostas (o mais votado até dá a solução rápida). Acho que educar as pessoas sobre como analisar e compreender as mensagens de erro é mais útil no longo prazo do que apenas fazer isso por elas. "Dê um peixe a um homem ..." e tudo mais.
Joachim Sauer
Obrigado pela observação lateral.
Venkatesh Goud
17

Tente fazer 9223372036854775807L. O Lno final informa ao Java que 9223372036854775807é um long.

Jontro
fonte
0

Eu tive esse problema no passado e resolvi isso escrevendo o valor na forma científica. por exemplo:

double val = 9e300;

fonte
-2
long ak = 34778754226788444L/l;

Ambos usam, mas por vez, apenas um usa L maiúsculo ou l minúsculo.

Por que usar L / l? Porque long faz parte do tipo de dados integral.

Akkushwaha
fonte