14

Why does the following code not generate an error?

System.out.println((char) 2147483647);

According to oracle datatypes, the maximum size for a char is 65,535.

  • char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
uranibaba
  • 712
  • 1
  • 13
  • 30
  • 5
    And what does it print? Not `2147483647`. Why not? There's your answer... – Boris the Spider Jun 12 '15 at 11:31
  • It does a narrowing conversion, 2147483647 is an int, and you are narrowing it to be a char. As you have mentioned the maximum value for char is 65535. If you do a, System.out.println((int)(char)2147483647); , you'll see it prints 65535 not 2147483647. HTH – Pavithra Gunasekara Dec 02 '15 at 01:50

5 Answers5

27

Why can I generate char beyond max value?

2147483647 is not a char but an int.

You're not assigning an invalid value to a char, you're casting a valid int to char and then Narrowing Primitive Conversion rules apply. See Java specs: §5.1.3.

In short you keep lowest 16 bits of original integer ("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.").

Why does the following code not generate an error?

Because it's not an error, it's a well-defined behavior.

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
6

You do a narrowing conversion from int to char, which is allowed see java spec: 5.1.3. Narrowing Primitive Conversion:

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.

The resulting char isn't larger than Character.MAX_VALUE. The compiler converts (char) 2147483647 to 65535

fabian
  • 80,457
  • 12
  • 86
  • 114
3

char is a 16bit data type to which a numeric value can be casted to.

When you cast a 32bit integer to a 16bit short (or to char) you loose the upper bits of your source.

Int32 i = 2147483647; // 0x7FFFFFFF
Int16 s = (Int16) i;  //     0xFFFF (65535)
char  c = (char)  i;  //     0xFFFF (65535)
abto
  • 1,583
  • 1
  • 12
  • 31
0

This works with any data type, it's called an integer overflow and when casting any bits beyond the size of the type you're casting to are cut off.

user_4685247
  • 2,878
  • 2
  • 17
  • 43
-1

Actually, the answer to your question is you can't.

Why you dont see any error?
Because Character.MAX_VALUE + 1 = Character.MIN_VALUE... Same as Integer.MAX_VALUE and others, JVM treats it as a loop to avoid this kind of problems... but gives false results when try to calculate....

Check this question for further and technical info

Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • Overflow? No...16 MSB bits are just discarded. – Adriano Repetti Jun 12 '15 at 11:33
  • 1
    @AdrianoRepetti I'm quotting question linked.. but how I understand it can *try* to overflow... but does not happen... – Jordi Castilla Jun 12 '15 at 11:36
  • There's no overflow when you cast. The most significant data is simply lost. This is the same behavior as older languages, like C++. Casting a primitive is the developer's way of saying, "Yes, I know I'm going to lose data, and I accept that consequence." Thus, developers should avoid casting unless they *need* to, because the compiler will protect you from doing stupid things by accident. – sfdcfox Jun 12 '15 at 20:58