This question already has answers here:
Strange java behaviour with conditional operator. Is it a bug?
(2 answers)
Closed 9 years ago.
public static void main(String[] args) {
Object o=true?new Integer(1):new Double(1.0);
System.out.println(o);
}
I am getting 1.0 as output, first upon above else statement is unreachable but how it auto type casted.
The JLS states that
Widening primitive conversion (§5.1.2) is applied to convert either or both
operands as specified by the following rules:
• If either operand is of type double, the other is converted to double.
that is in an expression
true? Integer(1) : Double(1.0)
since one of the operand here is a Double the return type is also double
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6
The keyword is "Numeric Promotion":
Numeric promotions are used to convert the operands of a numeric
operator to a common type so that an operation can be performed. The
two kinds of numeric promotion are unary numeric promotion (§5.6.1)
and binary numeric promotion (§5.6.2).
sᴜʀᴇsʜ ᴀᴛᴛᴀ already gave you a link explaining your concrete example.
Related
This question already has answers here:
XOR of two short integers
(3 answers)
Why does the Java API use int instead of short or byte?
(7 answers)
Closed 4 years ago.
If I compile this:
1 public class test {
2 public static void main (String args[]) {
3 byte bx = 1;
4 byte by = 2;
5
6 int iz = bx ^ by;
7 byte bz = bx ^ by;
8 byte cbz = (byte)(bx ^ by);
9 }
10 }
then I get this error:
test.java:7: error: incompatible types: possible lossy conversion from int to byte
bz = bx ^ by;
This led me on a brief journey resulting in me deciding ^ always results in an int in a bitwise context. I don't understand why that choice was made.
At first I thought it might have something to do with boxing (or unboxing) but I'm using a primitive type and so I don't think that is part of my confusion.
The only thing I can think of is that byte is promoted to int but I haven't found anything yet that says that's what happens.
Because, in Java, all numeric operators will promote operands to int, long, float, or double, as defined by JLS 5.6.2. Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
After the type conversion, if any, value set conversion (§5.1.13) is applied to each operand.
Binary numeric promotion is performed on the operands of certain operators:
The multiplicative operators *, / and % (§15.17)
The addition and subtraction operators for numeric types + and - (§15.18.2)
The numerical comparison operators <, <=, >, and >= (§15.20.1)
The numerical equality operators == and != (§15.21.1)
The integer bitwise operators &, ^, and | (§15.22.1)
In certain cases, the conditional operator ? : (§15.25)
This question already has answers here:
Unexpected type resulting from the ternary operator
(4 answers)
Closed 8 years ago.
Object myObject = true ? new Integer(25) : new Double(25.0);
System.out.println(myObject);
Strangely, it outputs 25.0 instead of 25
Whats going on?
Your code returns the second operand (new Integer(25)) as you expected, but it converts it to a Double due to the following rules.
Here's what JLS 15.25 says :
if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.
If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression (§15.28) of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U.
Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.
Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).
And the numeric promotion :
5.6.2. Binary Numeric Promotion
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
In your example, you have an Integer and a Double. They are unboxed to int and double and then the int is converted to a double.
There is some wierd autoboxing stuff going on - you can see it better if you use different numbers:
Object myObject = true ? new Integer(25) : new Double(22.0);
Now, myObject will still be assigned a Double(25.0), not the 22.0 you would expect if the conditional didn't work. Basically, because Java thinks you are doing some sort of calculation involving an int and a double it returns the result of the iif as a "double" primative and then autoboxes it back to a Double().
You could also get it to behave as expected by forcing it to treat the values as type Object():
Object myObject = true ? (Object) new Integer(25) : (Object) new Double(22.0);
After compilation
Object myObject = true ? new Integer(25) : new Double(25.0);
will be something as below
Object myObject = (double) new Integer(25);
So, it returns new Integer(25) as expected but it gets converted to double.
As Eran mentioned, as per JLS 5.6.2:
binary numeric promotion (§5.6.2) is applied to the operand types, and
the type of the conditional expression is the promoted type of the
second and third operands.
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted
to float.
Otherwise, if either operand is of type long, the other is converted
to long.
Otherwise, both operands are converted to type int.
This question already has answers here:
Adding char and int
(7 answers)
Closed 9 years ago.
I've got a strange issue with int to char conversion. Here's my code :
char a=100;
System.out.println(a);
System.out.println(a+1);
System.out.println();
System.out.println((char)a+1);
System.out.println((char)101);
System.out.println( (char)a+1==(char)101 );
It gave me this output :
d
101
101
e
true
which is definitly strange : two differents output seems to be the same when compared ! Why is it so ? And how to make a+1 beeing seen as a char ?
Thank you for your answer and sorry if there's some english mistakes, it's not my mothertongue.
In this case
System.out.println((char)a+1);
you are only converting the a to a char (which it is already). The addition makes the whole expression an int, so the overloaded PrintWriter#println(int) gets executed. For it to be seen as a char, do
System.out.println((char) (a+1));
In the JLS
The binary + operator performs addition when applied to two operands
of numeric type, producing the sum of the operands.
The type of an additive expression on numeric operands is the promoted
type of its operands.
and about promotion
Widening primitive conversion (§5.1.2) is applied to convert either or
both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted
to float.
Otherwise, if either operand is of type long, the other is converted
to long.
Otherwise, both operands are converted to type int.
When you use this way:
(char)a + 1
It firstly converts a => char, after this you add 1 of type integer.
And result of calculation is upcasted to integer type.
You can omit this tricky place if you will cast all expression together:
(char)(a + 1)
This question already has answers here:
Promotion in Java?
(5 answers)
Closed 9 years ago.
I have three short variables.
When I add two together and assign the result to the third, eclipse tells me that I need to cast it to a short !
short sFirst, sSecond, sThird;
sFirst = 10;
sSecond = 20;
sThird = sFirst + sSecond;
Hovever, when I do a simple assignment followed by an incremental assignment, all is fine.
short sFirst, sSecond, sThird;
sFirst = 10;
sSecond = 20;
sThird = sFirst;
sThird += sSecond;
Why is this ?
The JLS (§15.8.2) says this:
"The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands."
"Binary numeric promotion is performed on the operands (§5.6.2)."
That means that the operands of your expression are converted to int. So the addition will add an int to an int.
"The type of an additive expression on numeric operands is the promoted type of its operands."
In your case, int.
I won't speculate as to why it is done this way. However, it is no accident. If you look at the bytecode instruction set as defined in the JVM spec, you will see that there are arithmetic instructions for int, long, float and double ... but NOT for the smaller integer types.
This behavior is precisely specified in the Java Language Specification.
The answer to the question why it was so specified would be just speculation and not a real answer. My "educated guess", backed by Oli Charlesworth's, would be because the equivalent semantics apply to C and other similar languages. And the semantics in C are such (again an "educated guess") because they allow the compiler to produce the most optimal code.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Booleans, conditional operators and autoboxing
Java, Google Collections Library; problem with AbstractIterator?
The code below produces a NPE:
Integer test = null;
Integer test2 = true ? test : 0;
System.out.println(test2);
To correctly print out "null" without an exception requires this code:
Integer test = null;
Integer test2 = true ? test : (Integer)0;
System.out.println(test2);
It's obvious in the first example that "test" is being unboxed (converted to native int), but why? And why does changing the other expression in the ternary operator (as in the 2nd example) fix it? Can anyone provide some kind of narrative of exactly when, what, and why stuff in both of the examples gets boxed and unboxed?
From section 15.25 of the Java Language Specification:
The type of a conditional expression is determined as follows:
If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
If one of the second and third operands is of type boolean and the type of the other is of type Boolean, then the type of the conditional expression is boolean.
If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T.
If one of the operands is of type Byte and the other operand is a constant expression of type int whose value is representable in type byte, then the type of the conditional expression is byte.
If one of the operands is of type Short and the other operand is a constant expression of type int whose value is representable in type short, then the type of the conditional expression is short.
If one of the operands is of type; Character and the other operand is a constant expression of type int whose value is representable in type char, then the type of the conditional expression is char.
Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).
So it's following the final bullet, performing binary numeric promotion, which performs an unboxing conversion. So the type of the conditional operator expression is int, even though you're assigning it to an Integer. It's trying to perform the unboxing conversion on null, hence the exception.