115

It appears that when you type in a number in Java, the compiler automatically reads it as an integer, which is why when you type in (long) 6000000000 (not in integer's range) it will complain that 6000000000 is not an integer. To correct this, I had to specify 6000000000L. I just learned about this specification.

Are there other number specifications like for short, byte, float, double? It seems like these would be good to have because (I assume) if you could specify the number you're typing in is a short then java wouldn't have to cast it - that is an assumption, correct me if I'm wrong. I would normally search this question myself, but I don't know what this kind of number specification is even called.

azro
  • 53,056
  • 7
  • 34
  • 70
jbu
  • 15,831
  • 29
  • 82
  • 105

7 Answers7

208

There are specific suffixes for long (e.g. 39832L), float (e.g. 2.4f) and double (e.g. -7.832d).

If there is no suffix, and it is an integral type (e.g. 5623), it is assumed to be an int. If it is not an integral type (e.g. 3.14159), it is assumed to be a double.

In all other cases (byte, short, char), you need the cast as there is no specific suffix.

The Java spec allows both upper and lower case suffixes, but the upper case version for longs is preferred, as the upper case L is less easy to confuse with a numeral 1 than the lower case l.

See the JLS section 3.10 for the gory details (see the definition of IntegerTypeSuffix).

Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127
  • 10
    Late entry: removing potential sources of ambiguity is always good, and *I don't disagree*... but I believe if you find yourself confusing `1` with `l` and `0` with `O` (and so on), your *priority* is to set the font right (if you can), then worry about making sure you don't miss the Shift key. – davidcesarino Apr 02 '12 at 17:02
  • @SimonNickerson I have a question about suffixes... If I declare a _long_ or a _double_ variable like: `long _lo = 30;` and not `30L` does this mean my variable will be converted into _float_ ? Or in case of `_lo = _lo + 2.77` that `_lo` will be casted into _float_ although it was declared as _long_ – luigi7up Oct 19 '12 at 10:28
  • 1
    No, floats are not involved here. In the first case, `30` is an `int` which gets automatically converted via a widening conversion to a `long`. In the second case, your statement is illegal. You'd have to explicitly cast the right hand side to long, e.g. `_lo = (long) (_lo + 2.77)` – Simon Nickerson Oct 19 '12 at 11:49
  • 6
    @DavidCesarino changing the font fixes the ambiguity for you - in that particular editor where you've set it right. Changing l to L fixes the ambiguity for _everybody_ who might ever read your code including yourself when you are reading the code in a different Editor, IDE, looking at the source on the web (review tools, repositories, etc..). IMHO the priority is not to miss the Shift key. Btw. what font do you recommend? I like monospace and it's the default almost in all editors, CLIs etc that I've see and in this font `l` and `1` (`0` and `O` resp.) are fairly similar. – dingalapadum Apr 24 '17 at 19:57
  • 1
    @dingalapadum As I said, you're right. Removing sources of ambiguity is definitely a right thing to do. I just said you should try not to use any editor where you could easily mistake them. In other words, the old suggestion of coding defensively, but not depending on it. About the font, it is very personal, but I always use Deja Vu Sans Mono whenever I can because 1) it is monospaced; 2) it doesn't have ambiguities between characters; and 3) I like its shapes, beautiful and graceful, almost like a good, readable sans-serif font (other good programming fonts feel too "metallic" IMHO). – davidcesarino May 02 '17 at 11:04
  • I usually use Roboto mono on my IDEs, it makes it easy to read. – JoelBonetR Mar 28 '18 at 15:11
18

By default any integral primitive data type (byte, short, int, long) will be treated as int type by java compiler. For byte and short, as long as value assigned to them is in their range, there is no problem and no suffix required. If value assigned to byte and short exceeds their range, explicit type casting is required.

Ex:

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

to overcome this perform type casting.

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

In case of long data type, it can accept the integer value without any hassle. Suppose we assign like

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

in this case no suffix like L/l is required. By default value 2147483647 is considered by java compiler is int type. Internal type casting is done by compiler and int is auto promoted to Long type.

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

Here we need to put suffix as L to treat the literal 2147483648 as long type by java compiler.

so finally

long l = 2147483648L;// works fine.
Utpal Kumar
  • 425
  • 4
  • 11
  • 1
    it is confusing. why do we need to add `L` to cast it if it's already defined as `Long`. why doesn't the compiler treat the number as integer and cast it if `L` is added. – Ali Jan 29 '22 at 20:27
13

I hope you won't mind a slight tangent, but thought you may be interested to know that besides F (for float), D (for double), and L (for long), a proposal has been made to add suffixes for byte and shortY and S respectively. This would eliminate to the need to cast to bytes when using literal syntax for byte (or short) arrays. Quoting the example from the proposal:

MAJOR BENEFIT: Why is the platform better if the proposal is adopted?

cruddy code like

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

can be recoded as

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

Joe Darcy is overseeing Project Coin for Java 7, and his blog has been an easy way to track these proposals.

Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127
erickson
  • 265,237
  • 58
  • 395
  • 493
  • that would be nice...I've always found that all the casts are really annoying – jbu Apr 20 '09 at 20:48
  • I take it this didn't make it into Java 7. Any word on if it will make it into a future update or Java 8? – crush Aug 28 '13 at 21:12
  • @crush I tried looking into it a few months back, and as far as I could tell, the proposal had been abandoned. We did get _ in numeric literals and the `0b` prefix for binary literals though. Whoop. – erickson Aug 28 '13 at 22:15
  • This proposals are probably implemented on kotlin instead of java, as oracle don't want the community tell them how to work... we're on 2018 and still nothing about this proposal, sadly – JoelBonetR Mar 28 '18 at 15:17
9

These are literals and are described in section 3.10 of the Java language spec.

McDowell
  • 107,573
  • 31
  • 204
  • 267
1

Java has two types of data type :

  1. Primitive Data-Type
  2. Non-Primitive Data-Type

Certain data types require specifications like long, float, and double.

While assigning any of the above data types to any variable always remember to....

  • End the value with a "d" in double data type.
  • End the value with a "L" in long data type.
  • End the value with a "f" in float data type.

Example:

long number = 15000000000L;

float mysecondnum = 5.75f;

double mynumber = 19.99d;

More info:

  • The size of the long data type is 8 bytes.
  • The size of the float data type is 4 bytes.
  • The size of the double data type is 8 bytes.

The precision level of the long data type is up to 7-8 decimal points while the float data type is up to 15 decimal points.

Edit:

Along with this typecasting can be used to change the primitive data type from one to another.

  • Widening Casting(automatically): smaller type to a larger type size
  • Narrowing Casting(manually): larger type to a smaller size type
1

It seems like these would be good to have because (I assume) if you could specify the number you're typing in is a short then java wouldn't have to cast it

Since the parsing of literals happens at compile time, this is absolutely irrelevant in regard to performance. The only reason having short and byte suffixes would be nice is that it lead to more compact code.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
0

To understand why it is necessary to distinguish between int and long literals, consider:

long l = -1 >>> 1;

versus

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

Now as you would rightly expect, both code fragments give the same value to variable l. Without being able to distinguish int and long literals, what is the interpretation of -1 >>> 1?

-1L >>> 1 // ?

or

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

So even if the number is in the common range, we need to specify type. If the default changed with magnitude of the literal, then there would be a weird change in the interpretations of expressions just from changing the digits.

This does not occur for byte, short and char because they are always promoted before performing arithmetic and bitwise operations. Arguably their should be integer type suffixes for use in, say, array initialisation expressions, but there isn't. float uses suffix f and double d. Other literals have unambiguous types, with there being a special type for null.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • I would really be interested in what you meant back in the days. In both cases I get 2147483647 and I don't understand why I should expect something else. – The incredible Jan Apr 23 '20 at 14:01
  • @TheincredibleJan You would rightly expect `Integer.MAX_VALUE`, however if there was no way to distinguish between `int` and `long` literals it would be ambiguous. / I've no recollection of this question, but have clarified my answer anyway. – Tom Hawtin - tackline Apr 24 '20 at 16:02