This is normal behavior. Any integer with a negative value has a binary representation starting with infinite 1s.
So if you start out with say: -3 the binary representation looks like this:
...11 1101
So if we right shift this by 2 we get
...11 1111
Now for the unsgined/signed right shift. This relies on the fact that we don't have infinite digits in our integer. So say we have an 8bit integer assigned as -3 it looks like this:
1111 1101
If we do a signed shift, it will look at the MSB (most significant bit, the most left one) and preserve the value of that when shifting. So a signed shift right by 3 looks like this:
1111 1111
On the contrary, a unsigned right shift will not check the MSB and just shift right and fill with zeroes resulting in this:
0011 1111
This is exactly what you're seeing but the output truncates the preceding zeroes away.
If you don't know why negative integers are stored that way, check this answer.
As for why (b & 0xff) >>> 5
behaves differently
Integers in java are 32bit, that means the binary representation will have 32 digits. Your -59 will look like the following binary representation:
1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0111 1111 1111 1111 1111 1111 1110 == -59 >>> 5
If you now and this together with 0xff
you get the following:
1111 1111 1111 1111 1111 1111 1100 0101 == -59
0000 0000 0000 0000 0000 0000 1111 1111 == 0xff
0000 0000 0000 0000 0000 0000 1100 0101 == -59 & 0xff
0000 0000 0000 0000 0000 0000 0000 0110 == (-59 & 0xff) >>> 5