I'm confused with a small problem , see the following :
Double j = new Double(5); // No problem.
double j =5;//
//But
//Here the problem:
Double j = 5;
Long k =5;
Float g = 5.0;
I know the solution but I want to understand why in some situations the cast is done implicitly and in others not.
There is nothing wrong with
Double j = new Double(5);
because Java will convert 5 from an int to the double that a Double constructor will take. It will also convert the 5 to a double for the line:
double j =5;
That is a widening primitive conversion.
There is a problem with these lines.
Double j = 5;
Long k =5;
Float g = 5.0;
Java will not perform a widening primitive conversion (5 to 5.0 or 5L) and a boxing conversion (double to Double or long to Long) implicitly. It will perform either one implicitly, but not both. It also won't perform a narrowing primitive conversion here (5.0 to 5.0f).
The JLS, Section 5.2, states:
Assignment contexts allow the use of one of the following:
an identity conversion (§5.1.1)
a widening primitive conversion (§5.1.2)
a widening reference conversion (§5.1.5)
a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.
It doesn't explicitly allow what those last 3 lines are attempting to do: a widening primitive conversion followed by a boxing conversion.
Interestingly, Java does allow:
Number x = 5; // boxing followed by widening
double y = new Integer(5); // unboxing followed by widening
The problem with these three assignments is that although Java has rules about widening primitive-to-primitive conversions, it has no rules for primitive-to-wrapper conversions. In other words, there is no rule that would do a conversion in addition to auto-boxing.
Double j = 5; // 5 is an int literal. It can be auto-boxed only to Integer
Long k =5; // Same here
Float g = 5.0; // 5.0 is a double literal. It can be auto-boxed only to Double
You can fix these by adding a proper suffix or a proper cast, like this:
Double j = (double)5;
Long k = 5L;
Float g = (float)5.0;
Double j = new Double(5); double k =j;
Here unboxing is occurred. getting value from Wrapper object and assign to primitive data type(int,doulbe,float) double k= j; is equivalent to j.doubleValue(); return type is double
Double j = 5;
You want ti use like this, You have to mention data type, Double a=(double)5; or Double a= Double.valueOf(5);
this is autoboxing. With out knowing data type can't java cast, otherwise you should give correct primitive data type(5.0).
double d = 5; // widening
in above statement, widening is happening from primitive int to double
Double d = new Double(5); // wrapper class constructor used and passed with int type value 5, but returns wrapper class Double reference d with reference to value 5.0 as jvm will do widening on int type value 5 and return double type 5.0 which gets used by wrapper class Double constructor.
Double d = 5.0; // is auto boxing, it is same like Double d = new Double(5);
But, Double d = 5; // is erroneous as int type value 5 can not be auto boxed to double type value and referenced by Double type reference variable. jvm does not perform such primitive type widening for values to be referenced by wrapper class reference variable.
来源:https://stackoverflow.com/questions/24332413/java-auto-boxing-and-casting