int a1 = 65535;
char ch2 = (char) a1;
System.out.println(\"ASCII value corresponding to 65535 after being typecasted : \"+ch2);// prints?
char ch3 = 65535;
System.
Java's char
type holds a Unicode/UTF-16 code unit, one or two of which encode a codepoint. Not all 16-bit positive integers are valid code units. And, since you want to deal with char
instead of String
, you'll want to restrict the values to codepoints encoded with only one code unit.
65535 is not a valid UTF-16 code unit nor a valid Unicode codepoint.
As to your question, why you don't get an exception, I can only compare with other integer-like operations where you don't get an exception for overflows and similar exceptional outcomes. Languages vary in their design compromises.
I'll submit, if you are doing the right thing—the right way—with char
or Character
or String
, you won't run into problems like this. Forget about "ASCII still ranges from 0 to 127 as always, and the extended 8-bit character set, ISO-Latin-1." Java uses Unicode; Embrace it.
Okay, you have a couple of quite distinct questions there.
The first question, I think, is:
ch2
and ch3
Because you're outputting an invalid character. Java characters represent UTF-16 code points, not actual characters. Some Unicode characters, in UTF-16, require two Java char
s for storage. More about UTF-16 here in the Unicode FAQ. In UTF-16, the value 0xFFFF
(which is what your ch2
and ch3
contain) is not valid as a standalone value; even if it were, there is no Unicode U+FFFF character.
Re the output of ch22
: The reason you're seeing a little box is that you're outputting character 0
(the result of (char)65536
is 0
, see below), which is a "control character" (all the characters below 32 — the normal space character — are various control characters). Character 0
is the "null" character, for which there's no generally-accepted glyph that I'm aware of.
int a11 = 65536; char ch22 = (char) a11;
?Because that's how Java's narrowing primitive conversions are defined. No error is thrown; instead, only the relevant bits are used:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
char ch22 = (char) a11
worksFrom java specification
A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range.
[...]
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
char c = 65536
doesn't workFrom java specification
A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
- Byte and the value of the constant expression is representable in the type byte.
- Short and the value of the constant expression is representable in the type short.
- Character and the value of the constant expression is representable in the type char.
65536
is not inherently a char value
For example
1
is at the same time a byte, a short, a char, an int and a long value.256
is a short, char, int and long value, but not a byte value.65535
is a char, int and long value, but neither byte nor short value.-1
is a byte, short, int, long value, but not a char value.65536
is only an int and long value.char c = (char)65536;
will work