Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Help on Dan's exam 1

 
Gayatri Ganesh
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dan's exam 1 has this question (13) :
class JSC201 {
static byte m1() {
final char c = '\u0001';
return c; // 1
}
static byte m3(final char c) {return c;} // 2
public static void main(String[] args) {
char c = '\u0003';
System.out.print(""+m1()+m3(c));
}}
The answer is : complier error at //2.
I did not understand this. The explaination given for this answer is that at //2
char c is not a compile time constant while char c in function m1() is a compile time constant
so there will be an error at //2 not //1.
What is a compile-time constant ?
I was of the opinion that there will be an error at both //1 and //2.
Can anyone explain why there is no error at //1.
I also tried this instaed of the original m3():
static byte m3(final char c) {
char c1 = '\u0001';
return c1;
} // 2
But still it gives an error at //2.
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

What is a compile-time constant ?

Variables that are declared as compile-time constants IF AND ONLY IF they are declared as final.
Final variable means you cannot change the value of it after you have assigned one value to it. Thus, it becomes unchangable, which is a "constant" along with its life time (in this program/system).

I was of the opinion that there will be an error at both //1 and //2.
Can anyone explain why there is no error at //1.

The compilation fails is due to the precision.
What you want to return is a character, which is 16 bits, while the return type of the function is a byte, which is 8 bits.
For casting down with less "bit length", you need to explicitly define what you want to return. Auto-conversion happens ONLY FOR casting up.
If you change your code to:

It will then work.
Nick.
 
Gayatri Ganesh
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Nicholas.
But why did we not have to do a cast for //1 like this :
return (byte)c;
Instead code runs with
return c; // 1
???
Below is question13 from Dan's exam1.
class JSC201 {
static byte m1() {
final char c = '\u0001';
return c; // 1
}
static byte m3(final char c) {return c;} // 2
public static void main(String[] args) {
char c = '\u0003';
System.out.print(""+m1()+m3(c));
}}
-Gayatri.
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But why did we not have to do a cast for //1 like this :
return (byte)c;
Instead code runs with
return c; // 1
???

This is because "\u0001" is a valid value of a byte.
If you convert it into integer, its valid is 1, which fits into the byte value's range: -127 to + 128.
You provide this value during complication time, so the complier knows it is valid.

However, when you pass a character into a function, the value cannot be determined during complication time. Thus, the compiler does not know what value will be passed in (as a casting down may occur).
Consider a simplier example:
1. byte b1 = 1; // valid
2. byte b2 = 2; // valid
3. byte b3 = b1+b2; //invalid
Recall that the default type of literial of a numeric value is either integer or double, line 1 tries to put integer "1" into byte "b1", which works, becos it is a valid byte value which does not need casting, AND IT CAN BE DETERMINED during compliation time.
So does line 2.
However, for line 3, integer + integer returns integer, since it assigns b3 to the result of "b1+b2", which cannot be determined during compliation (becos b1+b2 is actually performed during runtime), we acutally tries to cast a byte into integer, which should be a "potential" problem.
Hope this makes clear.
Nick.
 
Gayatri Ganesh
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, it is clear now.
Thank you very much.
-Gayatri
 
jeff mutonho
Ranch Hand
Posts: 271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
why then does this
static byte m1() {
final char c = '\u0001';
return c; // 1
}
work and NOT this
static byte m3(final char c) {
char c1 = '\u0001';
return c1; //2
}
Line 2 gives a compilation error , saying
Type mismatch: cannot convert from char to byteJSC201.java
Why don't we get the same error message on line 1?Is it because of the "final" keyword?
 
Gayatri Ganesh
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, This is what I think is the reason. But I may be wrong.
since at //1 the return type is a final variable (compile time constant) its value cannot be changed,hence //1 is legal.
But at //2 char c1 which is returned is not a compile time constant (not final) so its value can be changed some where along the life of the program/system. Hence line //2 requires an explicit cast
return (byte) c1;
Anyone please correct me if i am wrong.
-Gayatri.
 
Gayatri Ganesh
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, This is what I think is the reason. But I may be wrong.
since at //1 the return type is a final variable (compile time constant) its value cannot be changed,hence //1 is legal.
But at //2 char c1 which is returned is not a compile time constant (not final) so its value can be changed some where along the life of the program/system. Hence line //2 requires an explicit cast
return (byte) c1;
Anyone please correct me if i am wrong.
-Gayatri.
 
jeff mutonho
Ranch Hand
Posts: 271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
from what I've read in the spec , the final keyword is what actually makes the difference. The value of the final variable is known at compile time so the cast is not required.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic