Especificação do número L do Java (longa)

95

Parece que quando você digita um número em Java, o compilador o lê automaticamente como um inteiro, e é por isso que quando você digita (longo) 6000000000(não no intervalo de inteiros), ele reclama que 6000000000não é um inteiro. Para corrigir isso, tive que especificar 6000000000L. Acabei de aprender sobre esta especificação.

Existem outras especificações de número, como short, byte, float, double? Parece que seria bom ter isso porque (presumo) se você pudesse especificar o número que está digitando é um curto, então java não teria que lançá-lo - isso é uma suposição, me corrija se eu estiver errado . Eu normalmente pesquisaria essa questão sozinho, mas não sei como esse tipo de especificação de número é chamado.

jbu
fonte

Respostas:

174

Existem sufixos específicos para long(por exemplo 39832L), float(por exemplo 2.4f) e double(por exemplo -7.832d).

Se não houver sufixo e for um tipo integral (por exemplo 5623), será considerado um int. Se não for um tipo integral (por exemplo 3.14159), será considerado a double.

Em todos os outros casos ( byte, short, char), é necessário o elenco como não há sufixo específico.

A especificação Java permite sufixos em maiúsculas e minúsculas, mas a versão em maiúsculas para longs é preferida, pois maiúsculas Lsão menos fáceis de confundir com um numeral do 1que em minúsculas l.

Consulte a seção 3.10 do JLS para obter os detalhes sangrentos (consulte a definição de IntegerTypeSuffix).

Simon Nickerson
fonte
9
Entrada tardia: remover possíveis fontes de ambigüidade é sempre bom, e eu não discordo ... mas acredito que se você se sentir confuso 1com le 0com O(e assim por diante), sua prioridade é definir a fonte correta (se puder ) e se preocupe em não perder a tecla Shift.
davidcsb
@SimonNickerson Tenho uma pergunta sobre sufixos ... Se eu declarar uma variável longa ou dupla como: long _lo = 30;e não 30L, isso significa que minha variável será convertida em flutuante ? Ou, no caso _lo = _lo + 2.77disso _lo, será lançado em float, embora tenha sido declarado tão longo
luigi7up
Não, os carros alegóricos não estão envolvidos aqui. No primeiro caso, 30é um intque é automaticamente convertido por meio de uma conversão de alargamento para um long. No segundo caso, sua declaração é ilegal. Você teria que lançar explicitamente o lado direito para longo, por exemplo_lo = (long) (_lo + 2.77)
Simon Nickerson
4
@DavidCesarino alterar a fonte corrige a ambigüidade para você - naquele editor específico onde você definiu corretamente. Mudar de l para L corrige a ambigüidade para todos que possam ler seu código, incluindo você mesmo, quando estiver lendo o código em um editor diferente, IDE, olhando o código-fonte na web (ferramentas de revisão, repositórios, etc.). IMHO a prioridade é não perder a tecla Shift. Btw. qual fonte você recomenda? Eu gosto de monoespaço e é o padrão em quase todos os editores, CLIs etc que vejo e nesta fonte le 1( 0e Oresp.) São bastante semelhantes.
dingalapadum
1
@dingalapadum Como eu disse, você está certo. Remover as fontes de ambigüidade é definitivamente a coisa certa a se fazer. Eu apenas disse que você deveria tentar não usar nenhum editor onde pudesse facilmente confundi-los. Em outras palavras, a velha sugestão de codificar defensivamente, mas não depender dela. Quanto à fonte, é muito pessoal, mas sempre uso Deja Vu Sans Mono sempre que posso porque 1) é monoespaçada; 2) não possui ambigüidades entre personagens; e 3) Gosto de suas formas, bonitas e graciosas, quase como uma fonte sans-serif boa e legível (outras fontes de boa programação parecem muito "metálicas" IMHO).
davidcsb
13

Espero que você não se importe com uma tangente ligeira, mas pensei que possa estar interessado em saber que, além de F(para float), D(para duplo) e L(por muito tempo), foi feita uma proposta para adicionar sufixos para bytee short- Ye Srespectivamente . Isso eliminaria a necessidade de converter em bytes ao usar a sintaxe literal para matrizes de bytes (ou curtas). Citando o exemplo da proposta:

PRINCIPAL BENEFÍCIO: Por que a plataforma é melhor se a proposta é adotada?

código cru como

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

pode ser recodificado como

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

Joe Darcy está supervisionando o Projeto Coin para Java 7 e seu blog tem sido uma maneira fácil de rastrear essas propostas.

Erickson
fonte
isso seria bom ... Eu sempre achei que todos os elencos são realmente irritantes
jbu
Suponho que isso não faça parte do Java 7. Alguma palavra sobre se isso vai chegar a uma atualização futura ou ao Java 8?
esmagamento
@crush Tentei averiguar há alguns meses e, pelo que eu sabia, a proposta havia sido abandonada. 0bEntretanto , obtivemos _ em literais numéricos e o prefixo para literais binários. Grito.
Erickson
Essas propostas são provavelmente implementadas em kotlin ao invés de java, já que o oracle não quer que a comunidade diga a eles como trabalhar ... estamos em 2018 e ainda nada sobre essa proposta, infelizmente
JoelBonetR
11

Por padrão, qualquer tipo de dado primitivo integral (byte, short, int, long) será tratado como tipo int pelo compilador java. Para byte e short , desde que o valor atribuído a eles esteja em seu intervalo, não há problema e nenhum sufixo é necessário. Se o valor atribuído a byte e short exceder seu intervalo, a conversão explícita de tipo será necessária.

Ex:

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

para superar este tipo de fundição.

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

No caso de tipo de dados longos, ele pode aceitar o valor inteiro sem qualquer problema. Suponha que atribuímos gosto

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

neste caso, nenhum sufixo como L / l é necessário. Por padrão, o valor 2147483647 é considerado pelo compilador java como tipo int. A conversão de tipo interno é feita pelo compilador e int é promovido automaticamente para tipo Longo.

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

Aqui, precisamos colocar o sufixo como L para tratar o literal 2147483648 como tipo longo do compilador java.

então finalmente

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

Esses são literais e são descritos na seção 3.10 das especificações da linguagem Java.

McDowell
fonte
1

Parece que seria bom tê-los porque (presumo) se você pudesse especificar o número que está digitando é um curto, então java não teria que lançá-lo

Como a análise de literais ocorre em tempo de compilação, isso é absolutamente irrelevante em relação ao desempenho. A única razão pela qual ter shorte bytesufixos seria bom é que leva a um código mais compacto.

Michael Borgwardt
fonte
0

Para entender por que é necessário distinguir entre inte longliterais, considere:

long l = -1 >>> 1;

versus

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

Agora, como você poderia esperar, ambos os fragmentos de código dão o mesmo valor à variável l. Sem ser capaz de distinguir inte longliterais, qual é a interpretação de -1 >>> 1?

-1L >>> 1 // ?

ou

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

Portanto, mesmo se o número estiver na faixa comum, precisamos especificar o tipo. Se o padrão mudasse com a magnitude do literal, haveria uma mudança estranha nas interpretações das expressões apenas com a mudança dos dígitos.

Isso não ocorre para byte, shorte charporque eles estão sempre promovida antes de realizar operações aritméticas e bit a bit. Indiscutivelmente, deveriam ser sufixos de tipo inteiro para uso em, digamos, expressões de inicialização de array, mas não há. floatusa o sufixo fe double d. Outros literais têm tipos não ambíguos, havendo um tipo especial para null.

Tom Hawtin - tackline
fonte
Eu realmente estaria interessado no que você quis dizer naquela época. Em ambos os casos, recebo 2147483647 e não entendo por que devo esperar outra coisa.
O incrível
@TheincredibleJan Você poderia legitimamente esperar Integer.MAX_VALUE, no entanto, se não havia nenhuma maneira de distinguir entre inte longliterais seria ambíguo. / Não me lembro dessa pergunta, mas esclareci minha resposta de qualquer maneira.
Tom Hawtin - tackline