Specifica del numero L (lungo) di Java


95

Sembra che quando digiti un numero in Java, il compilatore lo legge automaticamente come un numero intero, motivo per cui quando digiti (lungo) 6000000000(non nell'intervallo del numero intero) si lamenterà che 6000000000non è un numero intero. Per correggere questo, ho dovuto specificare 6000000000L. Ho appena saputo di questa specifica.

Esistono altre specifiche numeriche come short, byte, float, double? Sembra che questi sarebbero buoni da avere perché (presumo) se potessi specificare il numero che stai digitando è un breve, java non dovrebbe lanciarlo - questa è un'ipotesi, correggimi se sbaglio . Normalmente cercherò questa domanda da solo, ma non so nemmeno come viene chiamato questo tipo di specifica del numero.

Risposte:


174

Esistono suffissi specifici per long(eg 39832L), float(eg 2.4f) e double(eg -7.832d).

Se non è presente alcun suffisso ed è un tipo integrale (ad esempio 5623), si presume che sia un int. Se non è un tipo integrale (ad esempio 3.14159), si presume che sia a double.

In tutti gli altri casi ( byte, short, char), è necessario il cast in quanto non v'è alcun suffisso specifico.

Le specifiche Java consentono suffissi sia maiuscoli che minuscoli, ma longè preferibile la versione maiuscola per s, poiché Lè meno facile confondere le maiuscole con un numero 1rispetto alle minuscole l.

Vedere la sezione JLS 3.10 per i dettagli cruenti (vedere la definizione di IntegerTypeSuffix).


9
Ingresso in ritardo: rimuovere potenziali fonti di ambiguità è sempre positivo, e non sono in disaccordo ... ma credo che se ti trovi a confondere 1con le 0con O(e così via), la tua priorità è impostare correttamente il carattere (se puoi ), quindi preoccupati di assicurarti di non perdere il tasto Maiusc.
davidcsb

@SimonNickerson Ho una domanda sui suffissi ... Se dichiaro una variabile lunga o doppia come: long _lo = 30;e non 30Lsignifica che la mia variabile verrà convertita in float ? O in caso di _lo = _lo + 2.77ciò _loverrà gettato in galleggiante anche se è stato dichiarato lungo
luigi7up

No, i galleggianti non sono coinvolti qui. Nel primo caso, 30è un intche viene convertito automaticamente tramite una conversione di ampliamento in un file long. Nel secondo caso, la tua dichiarazione è illegale. Dovresti lanciare esplicitamente il lato destro a lungo, ad esempio_lo = (long) (_lo + 2.77)
Simon Nickerson

4
@DavidCesarino cambiando il carattere risolve l'ambiguità per te - in quel particolare editor in cui l'hai impostato correttamente. Cambiare da l a L risolve l'ambiguità per tutti coloro che potrebbero leggere il tuo codice, incluso te stesso, quando stai leggendo il codice in un diverso Editor, IDE, guardando il sorgente sul web (strumenti di revisione, repository, ecc.). IMHO la priorità è non perdere il tasto Shift. Btw. quale font mi consigliate? Mi piace il monospazio ed è l'impostazione predefinita in quasi tutti gli editor, CLI ecc. Che ho visto e in questo tipo di carattere le 1( 0e Orisp.) Sono abbastanza simili.
dingalapadum

1
@dingalapadum Come ho detto, hai ragione. Rimuovere le fonti di ambiguità è sicuramente una cosa giusta da fare. Ho appena detto che dovresti cercare di non usare nessun editor in cui potresti facilmente scambiarli. In altre parole, il vecchio suggerimento di codificare in modo difensivo, ma non dipendere da esso. Per quanto riguarda il font, è molto personale, ma uso sempre Deja Vu Sans Mono ogni volta che posso perché 1) è a spaziatura fissa; 2) non ha ambiguità tra i personaggi; e 3) Mi piacciono le sue forme, belle e aggraziate, quasi come un buon font sans-serif leggibile (altri buoni font di programmazione sembrano troppo "metallici" IMHO).
davidcsb

13

Spero non ti dispiaccia una leggera tangente, ma ho pensato che potresti essere interessato a sapere che oltre a F(per float), D(per double) e L(per lungo), è stata fatta una proposta per aggiungere suffissi per bytee short- Ye Srispettivamente . Ciò eliminerebbe la necessità di eseguire il cast su byte quando si utilizza la sintassi letterale per array di byte (o brevi). Citando l'esempio della proposta:

VANTAGGIO PRINCIPALE: perché la piattaforma è migliore se la proposta viene adottata?

codice rozzo come

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

può essere ricodificato come

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

Joe Darcy sta supervisionando Project Coin per Java 7 e il suo blog è stato un modo semplice per tenere traccia di queste proposte.


sarebbe carino ... ho sempre trovato che tutti i cast sono davvero fastidiosi
jbu

Presumo che questo non sia entrato in Java 7. Qualche parola su se lo farà in un futuro aggiornamento o Java 8?
schiacciare il

@crush Ho provato a esaminarlo alcuni mesi fa e, per quanto ne sapevo, la proposta era stata abbandonata. Tuttavia, abbiamo ottenuto _ in letterali numerici e il 0bprefisso per letterali binari. Whoop.
erickson

Queste proposte sono probabilmente implementate su kotlin invece che su java, poiché Oracle non vuole che la comunità dica loro come lavorare ... siamo nel 2018 e ancora nulla su questa proposta, purtroppo
JoelBonetR

11

Per impostazione predefinita, qualsiasi tipo di dati primitivo integrale (byte, short, int, long) verrà trattato come tipo int dal compilatore java. Per byte e short , fintanto che il valore loro assegnato è nel loro intervallo, non ci sono problemi e non sono richiesti suffissi. Se il valore assegnato a byte e short supera il loro intervallo, è richiesto il casting esplicito del tipo.

Ex:

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

per ovviare a questo tipo di casting eseguire.

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

In caso di tipo di dati lungo, può accettare il valore intero senza problemi. Supponiamo di assegnare like

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

in questo caso non è richiesto alcun suffisso come L / l. Per impostazione predefinita, il valore 2147483647 è considerato dal compilatore java è di tipo int. Il casting del tipo interno viene eseguito dal compilatore e int viene promosso automaticamente al tipo Long.

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

Qui dobbiamo mettere il suffisso come L per trattare il letterale 2147483648 come tipo lungo dal compilatore java.

così finalmente

Long l = 2147483648L;// works fine.


1

Sembra che questi sarebbero buoni da avere perché (presumo) se potessi specificare il numero che stai digitando è breve, java non dovrebbe lanciarlo

Poiché l'analisi dei letterali avviene in fase di compilazione, ciò è assolutamente irrilevante per quanto riguarda le prestazioni. L'unico motivo shortper cui bytesarebbe bello avere e suffissi è che porta a un codice più compatto.


0

Per capire perché è necessario distinguere tra inte longletterali, considera:

long l = -1 >>> 1;

contro

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

Ora, come ci si aspetterebbe giustamente, entrambi i frammenti di codice danno lo stesso valore a variable l. Senza essere in grado di distinguere inte longletterali, qual è l'interpretazione di -1 >>> 1?

-1L >>> 1 // ?

o

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

Quindi, anche se il numero è nell'intervallo comune, è necessario specificare il tipo. Se il valore predefinito cambiava con l'ampiezza del letterale, ci sarebbe stato uno strano cambiamento nelle interpretazioni delle espressioni semplicemente cambiando le cifre.

Questo non si verifica per byte, shorte charperché sono sempre promosso prima di eseguire operazioni aritmetiche e bit a bit. Probabilmente dovrebbero essere suffissi di tipo intero da utilizzare, ad esempio, in espressioni di inizializzazione di array, ma non c'è. floatusa il suffisso fe double d. Altri letterali hanno tipi non ambigui, con un tipo speciale per null.


Sarei davvero interessato a cosa intendevi in ​​quei giorni. In entrambi i casi ottengo 2147483647 e non capisco perché dovrei aspettarmi qualcos'altro.
L'incredibile

@TheincredibleJan Giustamente te lo aspetteresti Integer.MAX_VALUE, tuttavia se non ci fosse modo di distinguere tra inte longletterali sarebbe ambiguo. / Non ricordo questa domanda, ma ho comunque chiarito la mia risposta.
Tom Hawtin - tackline
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.