3

Why do I have to cast 0 to byte when the method argument is byte?

Example:

void foo() {
   bar((byte) 0);
}

void bar(byte val) {}

I know that if the argument is of type long I don't have to cast it, so I'm guessing that Java thinks of mathematical integers as integers runtime.

Doesn't it discourage the usage of byte/short?

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
Rob Fox
  • 5,355
  • 7
  • 37
  • 63
  • Here is a similar question that covers yours : http://stackoverflow.com/questions/5193883/how-do-you-specify-a-byte-literal-in-java – Rion Williams Sep 06 '11 at 18:24
  • You are asking about the difference. What should `(byte) Integer.MAX_VALUE` evaluate to? How about `(byte) 512`? – Stefan Kendall Sep 06 '11 at 18:25
  • 1
    @Stefan I am more of asking why doesn't java understand that 0 WILL fit into a byte. I know that integer to byte might cause data loss. – Rob Fox Sep 06 '11 at 18:28

3 Answers3

8

Because 0 is an int literal, and down-casting to byte from int requires an explicit cast (since there is the possibility of information loss.) You don't need an explicit cast from int to long, since no information could be lost in that conversion.

dlev
  • 48,024
  • 5
  • 125
  • 132
7

The literal 0 is an integer, and there is no automatic cast from integer -> byte, due to a potential loss of precision. For example, (byte)1024 is outside the valid range. Perhaps the compiler could be smarter and allow this for small integer literals, but it doesn't...

Widening to long is okay, since every integer can be a long with no loss of information.

And yes, for this reason I would almost never use short or byte in any APIs exposed by my code (although it would be fine for intermediate calculations)

Steven Schlansker
  • 37,580
  • 14
  • 81
  • 100
  • 3
    ++1 for the compiler should be smarter for literals. I like your icon, sir unicorn. – Stefan Kendall Sep 06 '11 at 18:26
  • This was the answer I was looking for. "Perhaps the compiler could be smarter and allow this for small integer literals, but it doesn't" +1 – Rob Fox Sep 06 '11 at 18:35
  • It is not the compiler at all -- it is the (Java) *language specification* and this is just how Java was specified. (A Java compiler that acted differently would go against the specification.) C# on the other hand, will nicely "widen up literals" starting at the smallest sized type but, once again, this is per (C#) *language specification*. –  Sep 06 '11 at 18:49
  • 1
    @pst: Then the language specification needs an updated. Semantics. – Stefan Kendall Sep 06 '11 at 20:19
  • 2
    @Stefan Kendall As far as I am concerned the entire Java language needs to be rewritten/redesigned ;-) –  Sep 06 '11 at 21:38
2

Integer literals are implicitly of type int, unless they are explicitly marked as long through an L suffix. There are no corresponding markers for short or byte.

Doesn't it discourage the usage of byte/short?

Perhaps it does, and rightfully so. There is no advantage in using individual bytes or shorts, and they often cause problems, especially since the introduction of autoboxing.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720