1. Overview
In this tutorial, we’ll explore the differences between the literal representation of a long type and the conversion of an int value to a long value using the cast operator.
2. Literal Representation
By default, Java treats all integral numeric values as of the int type. Similarly, for the floating-point values, the default type is double.
An integral numeric value is considered to be of the long type only if the value contains the letter “L” or “l” as a suffix:
long x = 1L;
However, the lowercase “l” looks like the number 1. To avoid confusion, we should consider using the uppercase version of the letter.
As we know, each primitive data type has its corresponding wrapper class, which comes with different methods we can use and, additionally, allows us to use primitive values within generics.
Thanks to the Java autoboxing functionality, we can assign the literal value to its wrapper class reference directly:
Long x = 1L;
Here, Java converts the long value to the Long object automatically.
Furthermore, when we define a long value using the literal representation, it always evaluates as a long data type.
3. Explicit Type Casting
Moving forward, let’s examine the cases when we’d need to use explicit type casting. As a quick refresher, the cast operator converts a value of one type into the type defined within parentheses.
3.1. Primitive Data Types
To convert a value from one primitive type to another, we need to perform either widening or narrowing of the primitive data type.
Furthermore, to transform the value of the type that supports a bigger range of numbers, we don’t need to perform any additional action:
int x = 1;
long y = x;
However, to fit the value into the type with a smaller numeric range, we need to use explicit type casting:
int x = 1;
byte y = (byte) x;
One thing to keep in mind here is the possible data overflow that happens if a number is too big to fit into the new type.
3.2. Wrapper Class
One way to convert the primitive data type into a wrapper class that doesn’t correlate with the primitive type is by using the cast operator and embracing the Java autoboxing feature:
int x = 1;
Long y = (long) x;
Here, we first converted the int value to a long value and then let Java convert the long type to Long using autoboxing.
4. Constant Expression
Now that we discussed the basics, let’s dig a little deeper and see how Java treats literal values and casts of primitive data types.
We typically use the term constant to describe values that don’t change after compilation. On a class level, we define them using the static and final keywords.
However, besides the class constants, Java recognizes expressions that can be computed at compile-time. These expressions are referred to as constant expressions.
According to the Java Language Specification (JLS), literal primitive values and casts of primitive data types are both considered constant expressions.
Therefore, Java treats both the literal representation of a long value and the explicit cast of an int data type to a long the same way.
5. Comparison Between 1L and (long) 1
Finally, let’s see how the literal representation of a long type differs from casting an int value to a long.
Firstly, performance-wise, there’s no difference between those two expressions. They’re both considered constants and are evaluated at the compile-time.
Moreover, we can compile both statements and compare their bytecode results using, for instance, the javap tool. We’ll notice they’re the same. They both use lconst_1 to push a long constant into the stack.
Secondly, using the literal representation can increase the readability of the code.
Lastly, when we define a constant expression using the literal, the value will always be of a long type. However, when we’re using the cast operator, the number we’re casting is of the int type.
Therefore, the following code won’t compile:
Long x = (long) 123_456_789_101;
Even though we’re storing the value in the Long data type, the number 123_456_789_101 is of the int type. The code is invalid since the number is outside the integer range.
On the other hand, the literal representation compiles successfully:
Long x = 123_456_789_101L;
6. Conclusion
In this article, we learned the differences between defining a long value using literal representation and casting an int value to a long.
To sum up, from Java’s point of view, they’re both constant expressions. To put it differently, in both cases, the actual value can be determined at the compile-time. However, using the literal representation of a number comes with some benefits, such as increased readability and preventing possible data overflow.