Are you required to define a Long variable as
Long myUserId = 1L; ?
How come you can't just do Long myUserId = 1; ?
Long myUserId = 1; // error
does not work, because 1 is an int.
It will get auto-boxed to:
Integer myUserId = 1; // ok
It will also get widened to:
long myUserId = 1; // also ok
but not both.
So, yes, you have to say
Long myUserId = 1L;
which is a long that can get autoboxed into a Long.
As to why it works that way (or rather does not work in this case): Most likely because auto-boxing was added later (in Java5), and had to be absolutely backwards-compatible. That limited how "smooth" they could make it.
Because otherwise, Java defaults all numeric types to an Integer.
The only reason "1L" is even allowed to be assigned to a Long (instead of the primitive long) is due to the "auto-boxing" introduced with Java 5.
Without the "1L", behind-the-scenes, this looks like the following without the "L":
Long myUserId = Integer.valueOf(1);
... which I hope obviously explains itself. :-)
Related
If i want to initialize a long of 1 or 0 do i need to add L to the end?
long l = 0L;
long k = 1L;
versus
long l = 0;
long k = 1;
Does it matter for low values?
If i want to initialize a long of 1 or 0 do i need to add L to the end?
Only if the value is larger than will fit in an int. Without the L (or l, but don't use that), the number is an int.
Does it matter for low values?
Not at all. Java's int-to-long conversion is well-defined, and works across the int range.
That doesn't mean that doing so is wrong in any way, of course. You might be doing it for clarity's sake, for instance.
There is a question in Java past exam paper that brothers me:
With implicit conversion of primitive data types, you can lose precision and get incorrect results.
A True, B False
The key to the answer is A: True
I think it will neither lose precision nor get incorrect results. I know the explicit conversion can lose precision and get incorrect results but not implicit one.
For example:
int i = 9;
short s = 3;
i = s; // implicit conversion, neither loose
//precision nor incorrect results
s = i; // compile error, do we call this implicit conversion?
//if yes, then the answer to question 3 is True,
//but I don't think this is an implicit conversion,
//so I think answer is false.
As states on the notes:
Implicit type conversion: The programmer does not make any attempt to convert the type, rather the type is automatically converted by the system under certain circumstances.
Could anyone please advise?
Many thanks.
Answer = A
float f = Long.MAX_VALUE;
System.out.println(Long.MAX_VALUE);
System.out.printf("%.0f", f);
output
9223372036854775807
9223372036854776000
There are some cases where the compiler will allow an implicit conversion, but you may still lose precision. For example:
long a = Long.MAX_VALUE; // 9223372036854775807
double b = a; // 9223372036854776000
See the JLS for more details on this.
There is implicit conversions in assignment operators. These can lose precision or cause an overflow. For regular assignments, implicit conversion only happen when the compiler knows it is safe. It can still lose precision, but not cause an overflow.
e.g.
final int six = 6;
byte b = six; // compiler uses constant propagation and value is in range.
int five = 5;
byte b2 = five; // fails to compile
double d = 5.5;
five += d; // compiles fine, even though implicit conversion drops the 0.5
// five == 10 not 10.5
five += Double.NaN; // five is now 0 ;)
I'm very confused right now.
I have a GregorianCalendar object which I give a specific date (Jan 1st 2010).
Calendar:
Calendar c = new GregorianCalendar();
c.set(2010, 0, 1);
System.out.println(c.getTime());
System.out.println(c.getTimeInMillis());
Output:
Fri Jan 01 13:12:57 CET 2010
1262347977927
Now when I try to create a long and store this number in it, the number is actually too big for my variable.
Storing in variable:
long timeStamp = 1262347977927;
// ERROR: The literal 1262347977927 of type int is out of range
But when I store the result directly into my variable, it works just fine.
Directly storing:
long timeStamp = c.getTimeInMillis();
System.out.println(timeStamp);
Output:
1262348451631
Why is the long that I get too big to be a long, yet not too long to be a long? I'm confused.
I'm using Java 6 and Eclipse Indigo if anyone would want to know.
EDIT: Thanks for all the instant answers... I feel really stupid now :p
You just have to add a L after the literal:
long timeStamp = 1262347977927L;
Always refer to the docs, Primitive Data Types:
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.
User the L at the end of the number:
long timeStamp = 1262347977927L;
It defines the Number as Long.
You must append an L or l
long timeStamp = 1262347977927L;
literal to the assigned value otherwise an integer value is assumed by the compiler
The former is preferable as the latter looks like a 1!
No 1262347977927 is not big enough for a long number (which is 8 bytes).
Make it like this:
long timeStamp = 1262347977927L;
L for long declaration.
Reason is that in Java by default all numbers are treated as int type unless you put switches like L in the end.
Or simple:
long timeStamp = c.getTimeInMillis()
Change
long timeStamp = 1262347977927;
to
long timeStamp = 1262347977927L;
Note that you need to suffix 'L' (preferred) or 'l' (suffixing this can lead to difficult to read code; there's a a java puzzler entry related to this) at the end .
It's not telling you that 1262347977927 can't fit into a long, it's telling you that it can't construct an int constant of value 1262347977927, before it even tries to assign it into the long variable. Notice how timeStamp is never mentioned in the error:
The literal 1262347977927 of type int is out of range
Use L after the number to mark it as a long constant, then you can assign it without problems:
long timeStamp = 1262347977927L;
Try appending 'L' after your number while assigning it to long variable.
In Java programming language widen and boxing doesn't work, but how does it work in following example?
final short myshort = 10;
Integer iRef5 = myshort;
Why does this work? Is this not the same as widen and then box?
But if I write the following code:
final int myint = 10;
Long myLONG = myint;
why it doesn't work?
Following what others have said, I can confirm that I can compile your first example with the Eclipse compiler, but not the second. With the javac compiler, both don't compile, as stated by Vlad
This seems to be a bug in either compiler! Let's consult the JLS to find out, which one is right :-)
With java 7 both the examples are not working. you will get below exception:
Type mismatch: cannot convert from short to Integer
Type mismatch: cannot convert from int to Long
Because the problem is not because of boxing but because of conversion.
You can either widen or box, but you can't do both.
You can do
final int myint = 10;
Long myLONG = (long) myint;
Neither works as it is (using javac 1.6.0_26 from Sun/Oracle, on Linux).
See also here.
b.java:4: incompatible types
found : short
required: java.lang.Integer
Integer iRef5 = myshort;
^
b.java:7: incompatible types
found : int
required: java.lang.Long
Long myLONG = myint;
^
2 errors
Let's examine what you're trying to do in detail:
final short myshort = 10;
Integer iRef5 = myshort;
The compiler will try to first box that short into an object, so that it can then perform the assignment (it cannot widen directly, since it is dealing with different types: an object and a primitive).
In short, this is equivalent to:
final short myshort = 10;
final Short box = new Short(myshort); // boxing: so that objects are assignable.
Integer iRef5 = box; // widening: this fails as Integer is not a superclass of Short
The same reasoning can be applied to your second example (which also fails), as is visible here. If your compiler does not complain on the first one, then there might be a bug with the compiler, because this is what's defined in the JLS. See the complete set of rules for conversion/promotion in the JLS here.
These are the promotion rules that apply to expressions in Java
all byte and short values are promoted to int
If one operand is long,the whole expression is promoted to long
If one operand is a float ,the whole expression is promoted to float
If one operand is double ,the whole expression is promoted to double
Hence short value is promoted to int. This is not widening.
"The conversion of a subtype to one of its supertypes is called widening"
You can box then wide but you can't widen and then box
So
final short myshort = 10;
Integer iRef5 = myshort;
is equivalent to
final short myshort = 10;
Integer iRef5 = 10;
which is perfectly valid
but
Long myLONG = 10;//this won't compile ,
But try with 10L it will so it will box then you can have it object too i.e. Object o = 10L;
See also
boxing-and-widening
scjp-cant-widen-and-then-box-but-you-can-box-and-then-widen
I'm using eclipse java ee to perform java programming.
I had the following line of code in one of my functions:
Long result = -1;
I got the following error:
Type mismatch: cannot convert from int to Long
I can't quite understand why when i add a number to the variable it provides this error.
How can this issue be resolved and why did it happen in the first place?
There is no conversion between the object Long and int so you need to make it from long. Adding a L makes the integer -1 into a long (-1L):
Long result = -1L;
However there is a conversion from int a long so this works:
long result = -1;
Therefore you can write like this aswell:
Long result = (long) -1;
Converting from a primitive (int, long etc) to a Wrapper object (Integer, Long etc) is called autoboxing, read more here.
-1 can be auto-boxed to an Integer.
Thus:
Integer result = -1;
works and is equivalent to:
Integer result = Integer.valueOf(-1);
However, an Integer can't be assigned to a Long, so the overall conversion in the question fails.
Long result = Integer.valueOf(-1);
won't work either.
If you do:
Long result = -1L;
it's equivalent (again because of auto-boxing) to:
Long result = Long.valueOf(-1L);
Note that the L makes it a long literal.
First of all, check you Java version: run "java -version" from command line.
In Java version prior to 1.5, the correct syntax is:
Long result = new Long(1L);
In java >1.5 it's done automatically. It's called "autoboxing".
The uppercase "L" tells Java that the number should be interpreted as long.
Long result = -1L;
Long result = (long) -1;
Long result
= Long.valueOf(-1); // this is what auto-boxing does under the hood
How it happened in the first place is that the literal -1 is an int. As of Java5, you can have it auto-boxed into an Integer, when you use it as on Object, but it will not be turned into a Long (only longs are).
Note that an int is automatically widened into a long when needed:
long result = -1; // this is okay
The opposite way needs an explicit cast:
int number = (int) result;
Long result = -1L;
-1 is a primitive int value, Long however is the wrapper class java.lang.Long. An primitive integer value cannot be assigned to an Long object. There are two ways to solve this.
Change the type to long
If you change the type from the wrapper class Long to the primitive type long java automatically casts the integer value to a long value.
long result = -1;
Change the int value to long
If you change the integer value from -1 to -1L to explicit change it to an long literal java can use this primitive value to automatically wrap this value to an java.lang.Long object.
Long result = -1L;
To specify a constant of type long, suffix it with an L:
Long result = -1L;
Without the L, the interpreter types the constant number as an int, which is not the same type as a long.