Java - short and casting
These are the relevant JLS sections:
JLS 5.1.1 Identity Conversion
A conversion from a type to that same type is permitted for any type.
JLS 5.2 Assignment Conversion
Assignment conversion occurs when the value of an expression is assigned to a variable: the type of the expression must be converted to the type of the variable. Assignment contexts allow the use of one of the following:
- Identity conversion
- [...]
In addition, if the expression is a constant expression of type
byte
,short
,char
orint
:
- A narrowing primitive conversion may be used if the type of the variable is
byte
,short
, orchar
, and the value of the constant expression is representable in the type of the variable.
The above rules explain all of the following:
short a = 4; // representable constant
short b = 5; // representable constant
short c = 5 + 4; // representable constant
short d = a; // identity conversion
short e = a + b; // DOES NOT COMPILE! Result of addition is int
short z = 32767; // representable constant
short z_ = 32768; // DOES NOT COMPILE! Unrepresentable constant
As to why this doesn't compile:
test(7); // DOES NOT COMPILE! There's no test(int) method!
It's because the narrowing conversion with constant is only defined for assignments; not for method invocation, which has entirely different rules.
JLS 5.3. Method Invocation Conversion
Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion. The designers of the Java programming language felt that including these implicit narrowing conversions would add additional complexity to the overloaded method matching resolution process.
Instead of explaining how method resolution works precisely, I will just quote Effective Java 2nd Edition, Item 41: Use overloading judiciously:
The rules that determine which overloading is selected are extremely complex. They take up thirty-three pages in the language specification, and few programmers understand all of their subtleties.
See also
- Varying behavior for possible loss of precision
short x = 3; x += 4.6;
compiles because of semantics of compound assignment
Why does casting a primitive type to a reference type is giving compilation error?
Because this
Long l = 1;
means assigning an int
(literal number without floating part are int
) to an Object
, here a Long
.
The autoboxing feature introduced in Java 5 doesn't allow to box from an int
to something else than a Integer
. So Long
is not acceptable as target type but this one would be :
Integer i = 1;
In your working example you convert the int to a long : (long)8
.
So the compiler can perfectly box long
to Long
.
Primitive type casting in java (disconcerting examples)
The first two are handled by the same case - JLS section 5.2:
In addition, if the expression is a constant expression (§15.28) of type byte,
short
,char
, orint
:
- A narrowing primitive conversion may be used if the type of the variable is
byte
,short
, orchar
, and the value of the constant expression is representable in the type of the variable.
The third is simply a case of regular conversion from a literal in source code to a double
: the nearest exact double
to 6.0000000000000000000000000000000001 is 6.0. So if you had:
double d = 6.0000000000000000000000000000000001;
that would assign a value of 6.0 to d
, as that's the closest representable double
to the value specified in the source code.
Conversion of one primitive type to another in java
Int literals (like 1
) are expressions of type int
.
Overload resolution proceeds in a number of stages, looking for a method which can accept the parameters with the types you are passing.
- If there is a single overload where the actual parameters have the same types as the formal parameters, invoke that.
- If there is a single non-varargs overload where the actual parameters can be automatically converted (e.g. by widening or un/boxing) to be of the same types as the formal parameters, invoke that.
- If there is a single varargs overload where the actual parameters can be automatically converted to be of the same types as the formal parameters invoke that.
- Otherwise, error.
These phases are applied in turn, continuing until a match is found.
Since there is an overload of m1
which takes int
, a match is found in phase 1, so no conversion of that value to another type needs to happen.
Is there a method in Java that mimics the cast of primitive type to Character?
If you're modifying bytecode, I think you do not need to cast to char
. In the bytecode, the char
type is a second-class citizen actually handled as an int
. From JVMS §4.9.2:
An instruction operating on values of type
int
is also permitted to operate on values of typeboolean
,byte
,char
, andshort
.As noted in §2.3.4 and §2.11.1, the Java Virtual Machine internally converts values of types
boolean
,byte
,short
, andchar
to typeint
.)
So while you can't, say, assign an int
to a char
in the Java language without an explicit cast, you can do that in the bytecode, since they have the same "verification type", which is int
. The bytecode representation of a char
is just an int
that happens to have its upper two bytes zero. So instead of:
char ch = num.charValue();
You would be able to get away with (in bytecode):
int ch = num.intValue() & 0x0000FFFF;
And then just pretend that ch
is a char
(e.g., pass it to methods that expect a char
or store it in a char
field or array).
However, if I understand it correctly, that's what the i2c
int
to char
cast instruction already does, so replacing it by an explicit AND operation is not going to be any simpler.
It's also surprisingly hard to find what actually happens if you cast a (signed)double into an (unsigned)char.
When you cast from float
or double
to byte
, short
, or char
, it first casts to int
, which saturates out-of-range values to Integer.MAX_VALUE
or Integer.MIN_VALUE
, and then truncates the bytes of the int
to fit the final type. See JLS §5.1.3 – Narrowing Primitive Conversion. The truncation step means that conversion of out-of-range floating-point values to byte
, short
, or char
is probably not going to give a useful result.
Directly casting primitive type to object is fine in Java?
Autoboxing is the automatic conversion that the Java compiler makes
between the primitive types and their corresponding object wrapper
classes.
int intValue = 0;
Integer value = intValue; // by Autoboxing
you can also convert it using valueOf method of wrapper class
Integer value = Integer.valueOf(intValue)
Check What code does the compiler generate for autoboxing? if you still have doubts.
Trouble casting integer object to primitive type
Arrays.asList(elements)
does not do what you think it does, it returns a list of containing the int[] array, not the elements of the array. You can not create a list of primitives. If you want to use List you must first convert the int
to Integer
.
You can get a List of Integer
with
List<Integer> arrList = Arrays.stream(elements).boxed().collect(Collectors.toList());
however, you still have a bug in your program where you will skip numbers.
for (int j = i + 1; j < arrList.size(); j++) {
if (arrList.get(j).equals(current) && occurrences >= maxOccurrences) {
arrList.remove(j); // This shortens the list causing us to skip the next element
j--; // One hackish way is to go back one step
} else if (arrList.get(j).equals(current)) {
occurrences++;
}
}
One solution is to loop backwards instead
for (int j = arrList.size() - 1; j > i; j--) {
if (arrList.get(j).equals(current) && occurrences >= maxOccurrences) {
arrList.remove(j);
} else if (arrList.get(j).equals(current)) {
occurrences++;
}
}
Why does casting a primitive type to a reference type is giving compilation error?
Because this
Long l = 1;
means assigning an int
(literal number without floating part are int
) to an Object
, here a Long
.
The autoboxing feature introduced in Java 5 doesn't allow to box from an int
to something else than a Integer
. So Long
is not acceptable as target type but this one would be :
Integer i = 1;
In your working example you convert the int to a long : (long)8
.
So the compiler can perfectly box long
to Long
.
Related Topics
Platform Independent Paths in Java
Best Way to Encode Text Data for Xml in Java
Java Ioexception "Too Many Open Files"
Convert Escaped Unicode Character Back to Actual Character
Read Whole Text Files from a Compression in Spark
How to Convert a String to Double in Java Using a Specific Locale
Randomly Select an Item from a List
Spring Boot 2.0.X Disable Security for Certain Profile
Java 8 Date and Time: Parse Iso 8601 String Without Colon in Offset
How to Sort Date Which Is in String Format in Java
How to Configure Jackson in Wildfly