2

I am initializing a byte[] in Java, using hexadecimal or binary notation.

It seems that auto-casting to byte is not done when the value approaches the capacity of a byte.

Solution is explicit cast to byte.

$ javac bitsandbytes/ByteBufferTest.java 
bitsandbytes/ByteBufferTest.java:9: error: possible loss of precision
    static byte[] byteArray = { 0xFF, (byte) 0xCC, 0xCC, 0b1000_0000, 0x2F, 0x01 };
                                ^
  required: byte
  found:    int
bitsandbytes/ByteBufferTest.java:9: error: possible loss of precision
    static byte[] byteArray = { 0xFF, (byte) 0xCC, 0xCC, 0b1000_0000, 0x2F, 0x01 };
                                                   ^
  required: byte
  found:    int
bitsandbytes/ByteBufferTest.java:9: error: possible loss of precision
    static byte[] byteArray = { 0xFF, (byte) 0xCC, 0xCC, 0b1000_0000, 0x2F, 0x01 };
                                                         ^
  required: byte
  found:    int
3 errors

enter image description here

2
  • What do you by mean approaches? Do you mean exceeds? Commented Feb 26, 2015 at 16:52
  • Forgot byte is signed in Java, forget this. Commented Feb 26, 2015 at 17:01

1 Answer 1

3

It seems that auto-casting to byte is not done when the value approaches the capacity of a byte.

No, it happens when the value is out of range. A byte in Java is in the range [-128, 127]. So 0xcc is out of range, for example... although this has nothing to do with which base you express the literal in.

If you have:

byte[] x = { 127 };
System.out.println(x[0]);

that will print 127, because it's in the range of byte. If you have:

byte[] x = { (byte) 128 };
System.out.println(x[0]);

... that will print -128. That would be very unexpected if you didn't have an explicit cast.

Admittedly an error message about "precision" is odd - and not what I receive. I see this:

error: incompatible types: possible lossy conversion from int to byte

It is a lossy conversion, so that's fine. I wouldn't talk about that being a precision issue though, which is what I'd expect for a conversion of (say) double to float.

In terms of the JLS, the relevant section is 5.2, which applies to each VariableInitializer in the ArrayInitializer.

This is the important part (emphasis mine):

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

The examples you've given aren't representable in the byte type, hence the error.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Jon. I am however puzzled why hex or binary notation is interpreted like this for byte types while I can perfectly define an int as 0xFFFF_FFFF without complaints from the compiler.
@Campa: It's a bit odd, yes. The JLS explicitly says that it's a bug for an int literal not to fit into 32 bits. I think the difference is that this is an integer literal - whereas there's no such thing as a "byte literal". There's just an implicit conversion from an integer literal to a byte. What you may find really surprising is that byte x = 0xff; is not valid, but byte x = 0xffff_ffff; is valid...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.