Javas L-Nummer (lange) Spezifikation

95

Es scheint, dass der Compiler beim Eingeben einer Zahl in Java diese automatisch als Ganzzahl liest. Wenn Sie also (lang) 6000000000(nicht im Bereich der Ganzzahl) eingeben, wird er sich beschweren, dass 6000000000es sich nicht um eine Ganzzahl handelt. Um dies zu korrigieren, musste ich angeben 6000000000L. Ich habe gerade von dieser Spezifikation erfahren.

Gibt es andere Nummernspezifikationen wie Short, Byte, Float, Double? Es scheint, als wären diese gut zu haben, denn (ich nehme an) wenn Sie angeben könnten, dass die Zahl, die Sie eingeben, kurz ist, müsste Java sie nicht umsetzen - das ist eine Annahme, korrigieren Sie mich, wenn ich falsch liege . Normalerweise würde ich diese Frage selbst suchen, aber ich weiß nicht, wie diese Art der Nummernspezifikation überhaupt heißt.

jbu
quelle

Antworten:

174

Es gibt spezielle Suffixe für long(zB 39832L), float(zB 2.4f) und double(zB -7.832d).

Wenn es kein Suffix gibt und es sich um einen integralen Typ handelt (z. B. 5623), wird angenommen, dass es sich um einen handelt int. Wenn es sich nicht um einen integralen Typ handelt (z. B. 3.14159), wird angenommen, dass es sich um a handelt double.

In allen anderen Fällen ( byte, short, char), müssen Sie die Besetzung als es keine spezifische Suffix ist.

Die Java-Spezifikation erlaubt sowohl Groß- als auch Kleinbuchstaben, jedoch wird die Großbuchstabenversion für longs bevorzugt, da Großbuchstaben Lweniger leicht mit einer Ziffer zu verwechseln sind 1als Kleinbuchstaben l.

Siehe JLS-Abschnitt 3.10 für die wichtigsten Details (siehe Definition von IntegerTypeSuffix).

Simon Nickerson
quelle
9
Verspäteter Einstieg: Das Entfernen potenzieller Mehrdeutigkeitsquellen ist immer gut, und ich bin nicht anderer Meinung ... aber ich glaube, wenn Sie 1mit lund 0mit O(und so weiter) verwechselt werden , besteht Ihre Priorität darin, die Schriftart richtig einzustellen (wenn Sie können) ), und sorgen Sie dann dafür, dass Sie die Umschalttaste nicht verpassen.
Davidcsb
@SimonNickerson Ich habe eine Frage zu Suffixen ... Wenn ich eine lange oder eine doppelte Variable deklariere wie: long _lo = 30;und 30Lbedeutet dies nicht, dass meine Variable in float konvertiert wird ? Oder im Falle , _lo = _lo + 2.77dass _lowird in gegossen werden Schwimmer obwohl es als erklärt wurde lange
luigi7up
Nein, Floats sind hier nicht beteiligt. Im ersten Fall 30handelt es sich um eine, intdie automatisch über eine erweiterte Konvertierung in eine konvertiert wird long. Im zweiten Fall ist Ihre Aussage illegal. Sie müssten explizit die rechte Seite zu lang werfen, zB_lo = (long) (_lo + 2.77)
Simon Nickerson
4
@DavidCesarino Durch Ändern der Schriftart wird die Mehrdeutigkeit für Sie behoben - in dem bestimmten Editor, in dem Sie sie richtig eingestellt haben. Durch Ändern von l in L wird die Mehrdeutigkeit für alle behoben, die Ihren Code jemals lesen könnten, einschließlich sich selbst, wenn Sie den Code in einem anderen Editor, einer anderen IDE, lesen und die Quelle im Web betrachten (Überprüfungstools, Repositorys usw.). IMHO ist es die Priorität, die Umschalttaste nicht zu verpassen. Übrigens. Welche Schriftart empfehlen Sie? Ich mag Monospace und es ist der Standard fast in allen Editoren, CLIs etc , dass ich sehe und in dieser Schriftart lund 1( 0und Oresp.) Ziemlich ähnlich ist .
Dingalapadum
1
@dingalapadum Wie gesagt, du hast recht. Das Entfernen von Mehrdeutigkeitsquellen ist definitiv richtig. Ich habe nur gesagt, Sie sollten versuchen, keinen Editor zu verwenden, in dem Sie sie leicht verwechseln könnten. Mit anderen Worten, der alte Vorschlag, defensiv zu codieren, aber nicht davon abhängig zu sein. Die Schrift ist sehr persönlich, aber ich benutze immer Deja Vu Sans Mono, wann immer ich kann, weil 1) sie monospaced ist; 2) es gibt keine Mehrdeutigkeiten zwischen den Zeichen; und 3) Ich mag seine Formen, schön und anmutig, fast wie eine gute, lesbare serifenlose Schrift (andere gute Programmierschriften fühlen sich meiner Meinung nach zu "metallisch" an).
Davidcsb
13

Ich hoffe, es macht Ihnen nichts aus, wenn Sie eine leichte Tangente haben, aber ich dachte, Sie könnten daran interessiert sein, das zu wissen F(für float).D (für Doppel) und L(lange), wurde ein Vorschlag gemacht worden Suffixe hinzufügen für byteund short- Yund Sjeweils . Dies würde die Notwendigkeit beseitigen, in Bytes umzuwandeln, wenn die Literal-Syntax für Byte-Arrays (oder kurze Arrays) verwendet wird. Zitat aus dem Vorschlag:

WICHTIGER VORTEIL: Warum ist die Plattform besser, wenn der Vorschlag angenommen wird?

grober Code wie

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

kann als neu codiert werden

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

Joe Darcy ist für Project Coin für Java 7 und seinen Blog verantwortlich war eine einfache Möglichkeit, diese Vorschläge zu verfolgen.

erickson
quelle
das wäre schön ... Ich habe immer festgestellt, dass alle Casts wirklich nervig sind
jbu
Ich nehme an, das hat es nicht in Java 7 geschafft. Gibt es ein Wort darüber, ob es in ein zukünftiges Update oder Java 8 kommen wird?
Crush
@crush Ich habe vor ein paar Monaten versucht, mich damit zu befassen, und soweit ich das beurteilen konnte, war der Vorschlag aufgegeben worden. Wir haben jedoch _ in numerischen Literalen und das 0bPräfix für binäre Literale erhalten. Whoop.
Erickson
Diese Vorschläge werden wahrscheinlich auf Kotlin anstelle von Java implementiert, da Orakel nicht möchte, dass die Community ihnen sagt, wie sie arbeiten sollen ... wir sind im Jahr 2018 und leider immer noch nichts über diesen Vorschlag
JoelBonetR
11

Standardmäßig wird jeder integrale primitive Datentyp (Byte, Short, Int, Long) vom Java-Compiler als Int- Typ behandelt . Für Byte und Short gibt es kein Problem und kein Suffix erforderlich, solange der ihnen zugewiesene Wert in ihrem Bereich liegt. Wenn der Wert für Byte und Kurzschluss den Bereich überschreitet, ist eine explizite Typumwandlung erforderlich.

Ex:

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

Um dies zu überwinden, führen Sie ein Gusstyp durch.

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

Bei einem langen Datentyp kann der ganzzahlige Wert problemlos akzeptiert werden. Angenommen, wir weisen wie zu

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

In diesem Fall ist kein Suffix wie L / l erforderlich. Standardmäßig wird der Wert 2147483647 vom Java-Compiler als int-Typ betrachtet. Das Casting des internen Typs wird vom Compiler durchgeführt und int wird automatisch zum Typ Long heraufgestuft.

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

Hier müssen wir das Suffix als L setzen, um das Literal 2147483648 vom Java-Compiler als langen Typ zu behandeln.

so endlich

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

Dies sind Literale und werden in Abschnitt 3.10 der Java-Sprachspezifikation beschrieben.

McDowell
quelle
1

Es scheint, als wären diese gut zu haben, denn (ich nehme an) wenn Sie angeben könnten, dass die Zahl, die Sie eingeben, kurz ist, müsste Java sie nicht umsetzen

Da das Parsen von Literalen zur Kompilierungszeit erfolgt, ist dies für die Leistung absolut irrelevant. Der einzige Grund, warum Suffixe shortund byteSuffixe schön wären, ist, dass sie zu kompakterem Code führen.

Michael Borgwardt
quelle
0

Um zu verstehen, warum zwischen intund longwörtlich unterschieden werden muss, betrachten Sie:

long l = -1 >>> 1;

gegen

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

Wie zu Recht zu erwarten, geben beide Codefragmente der Variablen den gleichen Wert l. Was ist die Interpretation, ohne unterscheiden intund longwörtlich sagen zu können -1 >>> 1?

-1L >>> 1 // ?

oder

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

Selbst wenn die Zahl im gemeinsamen Bereich liegt, müssen wir den Typ angeben. Wenn sich die Standardeinstellung mit der Größe des Literal ändert, ändert sich die Interpretation der Ausdrücke nur durch Ändern der Ziffern merkwürdig.

Dies tritt nicht auf byte, shortund charweil sie immer heraufgestuft werden, bevor arithmetische und bitweise Operationen ausgeführt werden. Wahrscheinlich sollten es Suffixe vom Typ Integer sein, die beispielsweise in Array-Initialisierungsausdrücken verwendet werden sollen, aber es gibt keine. floatverwendet Suffix funddouble d . Andere Literale haben eindeutige Typen, wobei es einen speziellen Typ für gibt null.

Tom Hawtin - Tackline
quelle
Es würde mich wirklich interessieren, was Sie damals gemeint haben. In beiden Fällen bekomme ich 2147483647 und ich verstehe nicht, warum ich etwas anderes erwarten sollte.
Der unglaubliche
@TheincredibleJan Sie würden zu Recht erwarten Integer.MAX_VALUE, aber wenn es keine Möglichkeit gibt, zwischen intund longLiteralen zu unterscheiden , wäre es mehrdeutig. / Ich habe keine Erinnerung an diese Frage, habe aber trotzdem meine Antwort geklärt.
Tom Hawtin - Tackline