Initialize java byte array: possible loss of precision

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

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow