59

I have generated a secure random number, and put its value into a byte. Here is my code.

SecureRandom ranGen = new SecureRandom();
byte[] rno = new byte[4]; 
ranGen.nextBytes(rno);
int i = rno[0].intValue();

But I am getting an error :

 byte cannot be dereferenced
2
  • 2
    There is a difference between byte and Byte. The latter is an object, which would support the .intValue() method. The first is the raw byte value and just assign it like int i = rno[0]; Commented Mar 6, 2012 at 10:20
  • 1
    See also stackoverflow.com/questions/2383265/convert-4-bytes-to-int Commented Mar 6, 2012 at 10:58

7 Answers 7

110

Your array is of byte primitives, but you're trying to call a method on them.

You don't need to do anything explicit to convert a byte to an int, just:

int i=rno[0];

...since it's not a downcast.

Note that the default behavior of byte-to-int conversion is to preserve the sign of the value (remember byte is a signed type in Java). So for instance:

byte b1 = -100;
int i1 = b1;
System.out.println(i1); // -100

If you were thinking of the byte as unsigned (156) rather than signed (-100), as of Java 8 there's Byte.toUnsignedInt:

byte b2 = -100; // Or `= (byte)156;`
int i2 = Byte.toUnsignedInt(b2);
System.out.println(i2); // 156

Prior to Java 8, to get the equivalent value in the int you'd need to mask off the sign bits:

byte b2 = -100; // Or `= (byte)156;`
int i2 = (b2 & 0xFF);
System.out.println(i2); // 156

Just for completeness #1: If you did want to use the various methods of Byte for some reason (you don't need to here), you could use a boxing conversion:

Byte b = rno[0]; // Boxing conversion converts `byte` to `Byte`
int i = b.intValue();

Or the Byte constructor:

Byte b = new Byte(rno[0]);
int i = b.intValue();

But again, you don't need that here.


Just for completeness #2: If it were a downcast (e.g., if you were trying to convert an int to a byte), all you need is a cast:

int i;
byte b;

i = 5;
b = (byte)i;

This assures the compiler that you know it's a downcast, so you don't get the "Possible loss of precision" error.

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

6 Comments

Using the Byte constructor is not a good idea. Just do Byte b = rno[0]; instead.
@xehpuk: I should have mentioned boxing conversions, done that now.
Why is boxing conversion superior to Byte constructor in this case? to my understanding the boxing conversion ends up using the Byte constructor in the end any way? is my understanding incorrect?
@user3772575: Yes. Boxing will use Byte.valueOf, not new Byte(), to avoid allocating a new instance if one already exists for that byte value; more here. (The spec doesn't actually say that, but that's what it does. You can tell by looking at the bytecode.)
Last I checked in Java 8 Byte class provides a static method called toUnsignedInt(byte). This should help converting easier and code more readable.
|
49
byte b = (byte)0xC8;
int v1 = b;       // v1 is -56 (0xFFFFFFC8)
int v2 = b & 0xFF // v2 is 200 (0x000000C8)

Most of the time v2 is the way you really need.

5 Comments

it's because the 32 bit machine generated the long 0xffffffc8, Thanks.
This is the correct answer, and v2 is almost always what you want. Implicit conversion of byte to int without the & 0xff is a source of bugs in Java.
This isn't really due to "bugs in Java" implicit conversion. It's due to developer misunderstanding. Java's byte primitive only supports values between -128 to 127. If someone tries to stuff an unsigned value (like 0xC8) into that, it can roll over with a bunch of leading ones (due to the twos complement notation). Similarly, for this question, a full bit space can have a sign bit set and a numeric promotion will do similarly.
Java is actually doing numeric conversion under the hood, according to the JLS, which means that both operands are converted to int primitives, anyway.
Not bugs in Java, bugs in user code written in Java :) Most programmers don't realize bytes are signed in Java, and frankly it is a stupid default behavior that they treat bytes as signed in the Java spec, but they did it for consistency with the other integral types, since none of them have unsigned versions. The same problem comes up with conversion of shorts to ints, since people also generally don't realize shorts are signed. (It's easier to trigger sign extension bugs with bytes though, because of the very limited range of values.) People do expect ints and longs to be signed though.
37

if you want to combine the 4 bytes into a single int you need to do

int i= (rno[0]<<24)&0xff000000|
       (rno[1]<<16)&0x00ff0000|
       (rno[2]<< 8)&0x0000ff00|
       (rno[3]<< 0)&0x000000ff;

I use 3 special operators | is the bitwise logical OR & is the logical AND and << is the left shift

in essence I combine the 4 8-bit bytes into a single 32 bit int by shifting the bytes in place and ORing them together

I also ensure any sign promotion won't affect the result with & 0xff

4 Comments

I would do (rno[0]&0x000000ff)<<24|(rno[1]&0x000000ff)<<16| ... etc. so I can then make that AND-ing operand a constant. Alternately, you could also just do ((int)rno[0])<<24|((int)rno[1])<<16| ... as the type casting automatically puts the byte values into primitive int space.
@ingyhere Your "Alternatively" suggestion is incorrect! See Sheng.W's answer. You almost always need to do (b & 0xff) to convert a byte to int, not ((int) b) or the equivalent implicit cast, because of sign extension.
You got me @LukeHutchison ... The second one in my comment only works for unsigned values (positive space) within the range of the Java byte primitive (up to 127).
The positive range of a signed value is not an unsigned value, it still has the sign of '+' :) Bytes and shorts and ints and longs are signed in Java, there is no unsigned version!
8

Primitive data types (such as byte) don't have methods in java, but you can directly do:

int i=rno[0];

2 Comments

No, it's Byte.intValue, while Byte is a class, byte is a primitive data type.
This answer is incomplete. See Sheng.W's answer. You almost always need to do (b & 0xff) to convert a byte to int, not ((int) b) or the equivalent implicit cast, int i = b;, because of sign extension for high-bit-set bytes. Forgetting to do this is a common source of bugs.
4

Bytes are transparently converted to ints.

Just say

int i= rno[0];

1 Comment

But note that the sign is preserved, which isn't always what you want (Java doesn't have unsigned bytes)
4

I thought it would be:

byte b = (byte)255;
int i = b &255;

Comments

-2

int b = Byte.toUnsignedInt(a);

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

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.