When reading bytes in order to build other primitive values such as ``++int++``s or ``++long++``s, the ``++byte++`` values are automatically promoted, but that promotion can have unexpected results.


For instance, the binary representation of the integer 640 is ``++0b0000_0010_1000_0000++``, which can also be written with the array of (unsigned) bytes ``++[2, 128]++``. However, since Java uses two's complement, the representation of the integer in signed bytes will be ``++[2, -128]++``  (because the ``++byte++`` ``++0b1000_0000++`` is promoted to the ``++int++`` ``++0b1111_1111_1111_1111_1111_1111_1000_0000++``). Consequently, trying to reconstruct the initial integer by shifting and adding the values of the bytes without taking care of the sign will not produce the expected result.  


To prevent such accidental value conversion, use bitwise and (``++&++``) to combine the ``++byte++`` value with ``++0xff++`` (255) and turn all the higher bits back off.


This rule raises an issue any time a ``++byte++`` value is used as an operand without ``++& 0xff++``, when combined with shifts.


== Noncompliant Code Example

----
  int intFromBuffer() {
    int result = 0;
    for (int i = 0; i < 4; i++) {
      result = (result << 8) | readByte(); // Noncompliant
    }
    return result;
  }
----


== Compliant Solution

----
  int intFromBuffer() {
    int result = 0;
    for (int i = 0; i < 4; i++) {
      result = (result << 8) | (readByte() & 0xff);
    }
    return result;
  }
----


== See

* https://wiki.sei.cmu.edu/confluence/x/kDZGBQ[CERT, NUM52-J.] - Be aware of numeric promotion behavior 


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::message.adoc[]

'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
