This week's book giveaway is in the Performance forum.
We're giving away four copies of The Java Performance Companion and have Charlie Hunt, Monica Beckwith, Poonam Parhar, & Bengt Rutisson on-line!
See this thread for details.
Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Problem returning a byte (was:Why it gives Compiler error?)

 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Guys,

Why it gives compiler error at line 2??



I'm confused as to why line 1 does not give any error?? An unsigned char is smaller than a signed type...is that the reason why it works at line 1. Is that an example of a covariant return type??

Thanks in advance.
[ December 04, 2006: Message edited by: Barry Gaunt ]
 
Ceenu Reddy
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think it's the problem with the Data type ranges. You are trying to returning the char(which is 2bytes) to byte (which is 1byte), no matter which is signed or unsigned.

You will get the compilation error that "possible loss of precision":

Type cast the char to byte when you are returning. And try with below code it will run successfully without any compilation errors:

class JSC201 {
static byte m1() {
final char c1 = '\u0001';
return c1;
}

static byte m2(final char c2) {
return ((byte)c2);
}

public static void main(String[] args) {

char c3 = '\u0003';

System.out.print("" + m1() + m2(c3) );

}
}
 
Vinayagar Karpagam
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe the final keyword is the key there in line 1.
since the char is final & the value can be put into a byte,
the compiler is not giving any errors.
But in the other case, it is not so.
 
Sanjeev Singh
Ranch Hand
Posts: 381
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jothi,
In //1 : '\u0001' is in the range of byte so no explicit widening/narrowing is required.
In //2 : Not all char is in the range of byte.
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Vinayagar is correct. In line one it knows at compile time that '\u0001' is small enough to fit into a byte. Line two is getting its value from the method parameter so the compiler doesn't know if the char size will fit into a byte or not so it complains.

Hope this helps, happy coding!
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, the point here is that a char is smaller than a byte and short and any conversions from a byte or short to char is considered as narrowing and requires an explicit cast. Am I right guys??

Can anyone confirm this??
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bytes are 8 bit
Char and short are 16 bit.

any conversions from a byte or short to char is considered as narrowing and requires an explicit cast


You're right in the fact that narrowing requires an explicit cast. However, what your method is doing is returning a 16 bit char to an 8 bit byte. This is a narrowing and requires an explicit cast as you said.

The first method does not require this because the compiler can tell that the char you are returning is small enough to fit into a byte so the complier will do an implicit cast for you.
 
Vinayagar Karpagam
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry Jothi, I guess you have misunderstood. If a byte is wider than char, the compilation wont fail. Just because char is wider than byte, the compiler gives error saying a char cannot be fit into a byte. Thats why the final keyword is required to ensure that the value of the char is so small that it can be fit into a byte.
So, char is wider than byte and short and any conversion from short or byte to char does not require explicit cast.
I guess this helps.
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Vinayagar,

I guess you are wrong. Don't go by the bit size. Any conversions from a byte or short to char requires an explicit cast.
 
Vinayagar Karpagam
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear Jothi,
Sorry I was wrong.
Any conversion from char to byte or short require explicit cast.
Any conversion from byte or short to char also require explicit cast as well.
I can understand that conversion between short & char require explicit cast because both are of same bit size.
But why conversion from byte to char also requires explicit cast even though the char is wider than byte.
Somebody clarify this?
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know little is that a char is a 16-bit unsigned and any conversions from an unsigned type to a signed type requires an explicit cast.
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think a byte requires an explicit cast because a byte can be a negative number where a char can never be a negative.

Have we all completely confused each other yet!
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg,

I guess this topic is worth the discussion. We are getting closer to the answer.

Any reasons to why the code below gives compiler error??

char c1 = 1;
byte b1 = c1; //gives compiler error here??

So as per our discussions above, a char should fir into a byte without a cast...Am I right?? then why does the above assignment gives an error??
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, a char (16 bit) is bigger than a byte (8 bit).

Just to confuse you more:



The reason that this fails as well is because a byte is signed so it can be a negative number but a char is unsigned so it cannot be a negative number.

If you have K&B Java 5 look at the table on page 50 and the description of chars on page 51.
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Greg.
 
Omkar Shetkar
Ranch Hand
Posts: 76
1
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,


public class Test
{

static byte m1(char c)
{
// final char c1 = '\u0001';
final char c1 = c;
return c1; // 1
}

static byte m2( final char c2)
{
return c2; // line 2
}

public static void main(String[] args)
{

char c3 = '\u0001';
System.out.print(""+m1(c3)+m2(c3)); // 3

}

} // End of class Test


In m1() Java compiler knows the exact value of c1 which in no way going to change but not the same for m2().
When changed m1() to pass the value dynamically, it will throw the same error.
So final value in the method... no error...

Omkar V S
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Omkar, did this compile for you? I thought 1 and 2 would give compiler errors? Method calls are runtime functions not compile time so the compiler wouldn't know if a valid implicit cast could be done?

I just turned off my development box so I can't test it right now.
 
Omkar Shetkar
Ranch Hand
Posts: 76
1
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

It will give compile time error both at line1 and line2. Here I wanted to say that if you give the final value within the method it will not give error but if you pass the final value it will. That's right Greg, run time knowledge of the value will throw an error...

Omkar V S
 
Anuragk kushwaha
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ranchers!!!

dear jothy and Greg,,,

i think, you all confused much, even me too after reading your posts.

always remember--->>>

<A>

"all conversions between char and the two integer types byte and short are considered narrowing conversions: the reason being that the conversions between the unsigned type char and the signed types byte or short can result in loss of information."..............from K&B 1.4

---
---- AND

<B>

"Additionally, implicit narrowing primitive conversions on assignment can occur in cases where all of the following 3 conditions are fulfilled:

1-- the source is a constant expression of either byte, short, char,
or int type

2--the destination type is either byte, short, or char type

3---the value of the source is determined to be in the range of the destination type at compile time"

Remember ir priority A then B,,,


---
hope this helps!!!
 
Joe Harry
Ranch Hand
Posts: 10124
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Anurag,

Thanks for the help. Can you give some examples explaining points <A> and <B> in your explanation??

That would be of great help.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic