Rhys
Rhys

Reputation: 101

A bit confused about java datatypes and literals

So I understand what a dataype and literal is but I am confused about one thing. Why do I have to put an L when the datatype is long? How come I don't have to do that for short or byte?

// Why does a not work but b does? Both are longs? 

long a = 9223372036854775807;
long b = 9223372036854775807L;

Upvotes: 1

Views: 97

Answers (3)

5gon12eder
5gon12eder

Reputation: 25409

There are only two integer literals types defined in Java: int and long. The latter is distinguished from the former by a suffix L or l. (A character literal is also of integral type (can be assigned to an int, for example) but the Java Language Specification (JLS) treats it separately from integer literals.)

Remember that (apart from inferring generic type parameters), the type of the left hand side of an assignment has no effect on the evaluation of the right-hand side. Therefore, if you assign something to a variable of type long, the expression will be evaluated first and only then will the result be converted to long (if possible and necessary).

The statement

long a = 10;

is perfectly valid. The right hand side expression consisting only of the integer literal 10 will be evaluated and then promoted to long which is then assigned to the variable a. This works well unless you want to assign a value that is too large to be represented in an int in which case you'll have to make the literal of type long as well.

This “problem” is not limited to literals. Consider the following statement that frequently bites new users:

long a = Integer.MAX_VALUE + 1;

The expression on the right hand side is evaluated using int arithmetic and therefore overflows. Only then the result (−2147483648) is promoted to long and assigned to a but it is too late by now. Had the 1 been written as 1L, the overflow would not have happened.

How come I don't have to do that for short or byte?

First, note that a literal of type int can hold any value you could possibly assign to a short or byte so the problem described above cannot occur. Moreover, it is not as much that you “don't have to” use a short or byte literal but that you cannot because such literals are not defined. This has always bothered me because it means that we often have to cast to byte if we want to call a function with a literal argument.

If you like reading standardese, you can look up the chapter about Integer Literals (§ 3.10.1) in the JLS.

Upvotes: 3

Ye Win
Ye Win

Reputation: 2098

If you didn't set L, the compiler will try to parse the literal as an int like as below sample scenario.

long accepts a value between the ranges of: -9,223,372,036,854 to +9,223,372,036,854,775,807. Now I have create a Long variable called testLong, although when I insert 9223372036854775807 as the value, I get an error stating:

"The literal of int 9223372036854775807 is out of range."

Solution is add a capital L to the end:

Upvotes: 1

LeleDumbo
LeleDumbo

Reputation: 9340

Clearly stated in the documentation:

"An integer literal is of type long if it ends with the letter L or l; otherwise it is of type int. It is recommended that you use the upper case letter L because the lower case letter l is hard to distinguish from the digit 1."

Your 2nd question is answered there as well:

"Values of the integral types byte, short, int, and long can be created from int literals"

Upvotes: 2

Related Questions