File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes question on integer promotion / assignment Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "question on integer promotion / assignment" Watch "question on integer promotion / assignment" New topic

question on integer promotion / assignment

Mark Neher

Joined: Apr 28, 2004
Posts: 9
On one of Dan Chisholm's exams, there was the following line buried in a question:

char primitiveChar = 'b'-'a';

The answer indicated that this was OK. I expected a compiler failure on this line -- I thought that the literal chars would be promoted to ints, and the assignment would be flagged for not casting it back down to a char. Indeed, the K&B book outlines a similar scenario for compiler error using bytes:

byte b = 3, c = 8;
byte d = b + c;

Trying to actually compile these does allow the char case, and gives an error on the (seemingly same to me) byte case. Can anyone explain the difference ??


Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Have you tried this?:

(gotta rush, going home time).

Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
shandilya popuru
Ranch Hand

Joined: Dec 21, 2004
Posts: 95
hi mark

char is just an unsigned int as long as the value is between 0 to 65536 u dont get an error
try this u get an error
char c;

cos the value`d be -1 out of the range of char
but this


this`ll return 1 that`d easily fit into chars range

hope that xplains ur doubt

Mark Neher

Joined: Apr 28, 2004
Posts: 9
OK, so

char a = 'a'; char b = 'b'; char c = b - a;

from Barry, gives a compiler error, as did

byte b = 3, c = 8; byte d = b + c;

from K & B. Further, changing K & B to

byte e = 3 + 8;

works, as did the original Dan Chisholm question of

char primitiveChar = 'b'-'a';

The pattern is clear; it still isn't obvious to me why the byte and char literals in the working examples aren't promoted to ints before the arithmetic. From K & B:

"We know that a literal integer is always an int, but more importantly -- the result of an expression involving anything int-sized or smaller is always an int. In other words, add two bytes together and you'll get an int -- even if those two bytes are tiny."

The two working examples would seem to fit this qualification: the result of an expression involving anything int-sized or smaller is always an int.
Javier Diaz

Joined: Mar 17, 2003
Posts: 16
I *think* it is because when you use an arith expresssion that involves just constants the compiler can optimize your arithmetic so the code in the .class has not got the arith, but just the result (use javap -c <ClassName> )

So the promotion rules do not apply as there is really no operation involved ...

Test 1

char one = 'b' - 'a';

0: iconst_1 // int 1
1: istore_1
2: return

Test 2

char one = 'c' - 'a';

0: iconst_2 //int 2
1: istore_1
2: return

Test 3 (out of range, COMPILE ERROR)
The compiler checks if the result would be out of range

char one = 'a' - 'b'; possible loss of precision
found : int
required: char
char one = 'a' - 'b';

Test 4 (loop around, force)

char one = (char) ('a' - 'b');

0: ldc #2; //int 65535
2: istore_1
3: return

Hope this helps

[ January 18, 2005: Message edited by: Javier Diaz ]
Animesh Shrivastava
Ranch Hand

Joined: Jul 19, 2004
Posts: 298
There is an implicit narrowing conversion from a byte, short, char, or int to a byte, short, or char when the source is a constant expression that can be evaluated at compile time and the value fits in the target. This does not apply to arguments in method invocations.

In the question given by you,
'a' and 'b' are literals which are constants,
So, it compiles fine,

Now as said by Barry,
this would give a compiler error
char a = 'a';
char b = 'b';
char c = b - a;

Because here a, b are not constants

Going through the explanation above the below would not give any compiler error,
final char a = 'a';
final char b = 'b';
char c = b - a;

For more info on this,
See JLS 5.2 Assignment Conversion.
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272

Nice answer.

Mike Gershman
SCJP 1.4, SCWCD in process
Mark Neher

Joined: Apr 28, 2004
Posts: 9
Thanks for the answers. I was looking at the JLS yesterday, but had not yet found the relevant section.

Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Now I come back and everything is done

Here's another interesting junk of JLS:

15.28 Constant Expression


A compile-time constant expression is an expression denoting a value of primitive type or a String that is composed using only the following:

* Literals of primitive type and literals of type String
* Casts to primitive types and casts to type String
* The unary operators +, -, ~, and ! (but not ++ or --)
* The multiplicative operators *, /, and %
* The additive operators + and -
* The shift operators <<, >>, and >>>
* The relational operators <, <=, >, and >= (but not instanceof)
* The equality operators == and !=
* The bitwise and logical operators &, ^, and |
* The conditional-and operator && and the conditional-or operator ||
* The ternary conditional operator ? :
* Simple names that refer to final variables whose initializers are constant expressions
* Qualified names of the form TypeName . Identifier that refer to final variables whose initializers are constant expressions

Compile-time constant expressions are used in case labels in switch statements (�14.10) and have a special significance for assignment conversion (�5.2).

A compile-time constant expression is always treated as FP-strict (�15.4), even if it occurs in a context where a non-constant expression would not be considered to be FP-strict.

Examples of constant expressions:

Integer.MAX_VALUE / 2
2.0 * Math.PI
"The integer " + Long.MAX_VALUE + " is mighty big."
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
Mark , may be my explanation you will not like but simple one :

if you are assigning a variable into a variable ( x = y ) then you have to make sure to compiler that you will not go to the out of range of left hand side variable ( x ) .
Like this will give no error at compile time .
Andris Jekabsons
Ranch Hand

Joined: Jan 20, 2004
Posts: 82
Right, because "y" is a constant (by virtue of being defined "final").
Remove the "final" part, and you'll have a compile-time error.
I agree. Here's the link:
subject: question on integer promotion / assignment
Similar Threads
Implicit Narrowing
Compile Time Constant
Implicit Narrowing
Widening and narrowing conversion questions
Byte b = new Byte(123); //fails to compile ! :mad: