Initialize a Long in Java

Initialize a long in Java

  1. You should add L: long i = 12345678910L;.
  2. Yes.

BTW: it doesn't have to be an upper case L, but lower case is confused with 1 many times :).

Long Literals in Java

tl;dr

is there any difference … int x = 100L; versus long x = 100;

Yes. There is a major difference.

  • The first will not compile, and will not run. You cannot cram a 64-bit long into a 32-bit int.
  • The second is the opposite of the first, a widening of a 32-bit int primitive integer literal while being assigned to a 64-bit long primitive integer variable.

Details

There is much misinformation in the other Answers.

32-bit vs 64-bit integer primitives

The L seen above means “64-bit int integer primitive” whereas the absence of a L in an integer literal means “32-bit int integer primitive”.

The following line fails to compile. You are attempting to place a 64-bit long primitive literal into a 32-bit int variable. Square peg, round hole. One of the compiler’s jobs is to stop such nonsense.

int x = 100L ;  // BAD — compiler fails — Cannot place a 64-bit `long` `int` primitive in a 32-bit `int` variable.

Error … incompatible types: possible lossy conversion from long to int

Let’s correct that line by dropping the L, assigning a 32-bit int literal to a 32-bit int variable.

int x = 100 ;  // 32-bit `int` integer primitive literal being stored in a 32-bit `int` integer variable. No problem, no issues.

Primitives, not objects

Notice that, contrary to some other Answers seen on this page, the code above has no objects, only primitives.

Widening from 32-bit to 64-bit

In the next line, you are first creating a 32-bit int primitive with the “100” part. That 32-bit int primitive is then assigned to a 64-bit long primitive. Java fills in the extra thirty-two bits with zeros, so effectively you end up with the same number.

long x = 100 ;  // 32-bit `int` integer primitive being stored in a 64-bit `long` integer primitive. The extra 32-bits are filled in with zeros automatically by Java.

As noted in a comment by Andreas, this conversion from 32-bit to 64-bit integers is technically called widening. See JLS 5.1.2 Widening Primitive Conversion for a technical discussion.

Some people, including me, consider such code using literals that depend on automatic widening to be poor form. Your intentions as a programmer are ambiguous. So I would write that code using the appended L, like this long x = 100L ;. But some folks would consider this position to be needlessly worried about an inconsequential matter.

Casting

Contrary to some other Answers, there is no casting involved in the code seen above.

Here is an example of casting. We start with a 64-bit long primitive. When then cast to an int primitive, lopping off the higher 32-bits. The (int) tells the compiler “yes, I know I am risking data loss in chopping off 32 of my 64 bits, but go ahead and do it, I am taking responsibility for this act”.

int x = (int) 100L ;  // Start with a 64-bit `long` primitive literal, lop off 32 of the 64 bits, resulting in a 32-bit `int` primitive being assigned to a 32-bit primitive variable.

In this particular example, there is no problem, as a value of one hundred fits with the lower 32-bits, so the set of higher thirty-two bits being excised are all zeros. So no damage in this case. But also in this case, this code is senseless, and should not be done in real work. Indeed, in real work you would only rarely, if ever, have a productive reason to lop off half of a 64-bit integer’s bits by casting.

Narrowing with Math.toIntExact

A better alternative to casting is to call Math.toIntExact. You pass a long primitive to this method, and it returns an int, the result of narrowing the 64-bit integer to 32-bit integer. The advantage over casting is that an ArithmeticException is thrown if overflow occurs. So you will be informed of any data loss.

try {
int x = java.lang.Math.toIntExact( 100L ) ;
} catch ( ArithmeticException e ) {
… // Handle data loss, the overflow in going from 64-bits to 32-bits.
}

Objects

Because some other Answers incorrectly raised the subject of objects and auto-boxing, I'll mention a bit about that.

The wording Long with an uppercase L in the front means the Long class rather than the long primitive. I'll not explain the distinction here, except to say I wish Java had never made explicit use of primitives and had instead stuck to only classes. Indeed, there is a remote possibility that a version of Java in the far future may do exactly that (hide the existence of primitives).

But here and now, there is a distinction between classes/objects and primitives. To help smooth over that distinction, Java supports auto-boxing. As a convenience, in most scenarios the Java compiler and runtime can detect when your code is assigning a primitive to where an object is expected, and vice-versa.

Long myLongObject = 100L ;  // This works because Java automatically detects the primitive `long` being assigned to an object of class `Long`, and instantiates a `Long` object to hold that number value.

That line above effectively is treated as if it is:

Long myLongObject = Long.valueOf( 100L ) ;

And is would be logically equivalent to the following, but technically this next line fails (compiler error) because there is no need for the L in the string as the string is assumed to contain digits of a 64-bit integer. In other words, this input string is not an integer literal, so the L is superfluous and not allowed.

Long myLongObject = Long.valueOf( "100L" ) ;  // Compiler error. The `L` is not allowed because it is redundant. 

Just drop the L from that String input, as the input is assumed to represent a 64-bit number.

Long myLongObject = Long.valueOf( "100" ) ;

Java will also automatically widen from a 32-bit int before also doing the autoboxing. So, the lines above are also effectively the same as this.

Long myLongObject = Long.valueOf( 100 ) ;  // 32-bit `int` primitive literal automatically widened to a 64-bit `long`, then passed as argument to the `valueOf` method that takes only a `long`. 

Again, the code seen in the Question has no involvement with classes/objects. This section of this Answer would be irrelevant except that other incorrect Answers raised the issues of objects & auto-boxing.

Initialize ArrayListLong

Explanation

Java automatically transforms int to long if needed.

However, Java does not do the same if a transformation from Integer to Long is needed.

The function Arrays.asList(...) returns a List<E> with E being the type used as parameters. As you use 1, 2, 3 the type is int. However the generic usage of data-types as List<int> is not possible in Java (at least currently). Therefore it automatically transforms int to Integer and produces a List<Integer> object. This process is called auto-boxing, Java can do this for all data-types to their corresponding object representation.

If you now use the constructor new ArrayList<Integer>(List<E> list) it expects E to be something of type Integer. So a List<Integer> works as input.

But when you use new ArrayList<Long>(List<E> list) obviously E needs to be of type Long. However the object Integer is not of type Long thus it does not accept the parameter. The first common type of Integer and Long is the abstract class Number (which also holds Double, Float and others) (documentation).


Solution

So it all revolves around the input 1, 2, 3 being interpreted as int instead of long. You can fix this by explicitly telling Java to interpret the numbers as long, you do so by appending l or L after the number:

new ArrayList<Long>(Arrays.asList(1L, 2L, 3L));

Now you receive a List<Long> which then is added to an ArrayList<Long>.


Note that the same technique can be used to explicitly interpret decimal numbers as float instead of double: 1.5F or 1.5f

initialize long number

append L to the end to make it a long literal

long fixedKey=0123456701234567L; //error on this line

Java new long(0)

I am going to improve upon the answers by @Rocket and @ParkerHalo to explain why the new Long(0) doesn't work.

So the problem with the if line of code is that the new Long(0) creates an object of class Long, however you aren't compairing classes, want you are comparing are primitive types. Primitive types have no methods and are basally a set amount of memory dedicated to storing a number (Read the comments). They were created with C and most (if not all) made their way into Java. However the Long Class has various methods to make working with longs easier in some cases.

You cannot compare them in this way because the new Long(0) returns a reference to a class, not a primitive type.

The quickest way to get your code up and running is to do as @ParkerHalo suggested and compare the value returned to a primitive long with the value of Zero. So if you wanted to see if it was Zero you would use:

if(item.label_id.longValue() == 0L) {

And you can replace the 0 with other values, as long as you keep the L for longs.

Hope this helps!



Related Topics



Leave a reply



Submit