java中字节到int的转换

java中字节到int的转换,java,type-conversion,Java,Type Conversion,我已经生成了一个安全的随机数,并将其值放入一个字节。这是我的密码 SecureRandom ranGen = new SecureRandom(); byte[] rno = new byte[4]; ranGen.nextBytes(rno); int i = rno[0].intValue(); 但我得到了一个错误: byte cannot be dereferenced 基本数据类型(如byte)在java中没有方法,但您可以直接执行以下操作: int i=rno[0]; 您的数

我已经生成了一个安全的随机数,并将其值放入一个字节。这是我的密码

SecureRandom ranGen = new SecureRandom();
byte[] rno = new byte[4]; 
ranGen.nextBytes(rno);
int i = rno[0].intValue();
但我得到了一个错误:

 byte cannot be dereferenced
基本数据类型(如byte)在java中没有方法,但您可以直接执行以下操作:

int i=rno[0];

您的数组由
字节
原语组成,但您试图对它们调用一个方法

字节
转换为
整数
,无需执行任何显式操作,只需:

int i=rno[0];
…因为这不是一种沮丧

请注意,
byte
-to-
int
转换的默认行为是保留值的符号(请记住
byte
在Java中是有符号类型)。例如:

byte b1 = -100;
int i1 = b1;
System.out.println(i1); // -100
如果您认为字节是无符号的(156),而不是有符号的(-100),那么在Java8中有:

在Java 8之前,要获得
int
中的等效值,需要屏蔽符号位:

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

为了完整起见#1:如果出于某种原因(您不需要在此处),您确实想使用
字节
的各种方法,您可以使用:

或:

但再说一次,这里不需要这个


为了完整起见#2:如果是向下转换(例如,如果您试图将
int
转换为
byte
),则只需进行向下转换:

int i;
byte b;

i = 5;
b = (byte)i;

这可以确保编译器知道这是一个向下转换,因此不会出现“可能的精度损失”错误。

字节被透明地转换为整数

就说

int i= rno[0];

如果你想把4个字节合并成一个整数,你需要这样做

int i= (rno[0]<<24)&0xff000000|
       (rno[1]<<16)&0x00ff0000|
       (rno[2]<< 8)&0x0000ff00|
       (rno[3]<< 0)&0x000000ff;
inti=(rno[0]
大多数情况下,v2是您真正需要的方式。

我认为它应该是:

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

字节和字节之间存在差异。后者是一个对象,支持
.intValue()
方法。第一个是原始字节值,只需像
int i=rno[0]那样分配它
另请参见否,它是
字节.intValue
,而
字节
是一个类,
字节
是一个原始数据类型。此答案不完整。请参见Sheng.W的答案。您几乎总是需要执行
(b&0xff)
字节
转换为
int
,而不是
((int)b)
或等效的隐式强制转换,
int i=b;
,因为高位集字节的符号扩展。忘记这样做是常见的错误源。但请注意,符号被保留,这并不总是您想要的(Java没有无符号字节),使用字节构造函数不是一个好主意。只需执行
Byte b=rno[0];
相反。@xehpuk:我应该提到装箱转换,现在就这么做了。为什么装箱转换在这种情况下优于字节构造函数?据我所知,装箱转换最终以任何方式使用字节构造函数结束?我的理解不正确吗?@user3772575:是的。装箱将使用
Byte.valueOf
,而不是e> new Byte()
,以避免在该字节值已经存在的情况下分配新实例;(规范,但它就是这样做的。您可以通过查看字节码来判断。)上一次我签入Java 8字节类时,提供了一个名为toUnsignedInt(Byte)的静态方法。这将有助于更轻松地转换和更可读的代码。我会这样做(rno[0]&0x000000ff)@ingyhere您的“Alternative”建议不正确!请参见Sheng.W的答案。由于符号扩展,您几乎总是需要(b&0xff)将字节转换为int,而不是((int)b)或等效的隐式强制转换。您得到了@LukeHutchison…我的注释中的第二个选项仅适用于无符号值(正空格)在Java字节原语的范围内(最多127个)。有符号值的正范围不是无符号值,它仍然有“+”符号:)字节和短整数和长整数在Java中有符号,没有无符号版本!这是因为32位机器生成了长0xFFFFC8,谢谢。这是正确的答案,v2几乎总是您想要的。在没有
&0xff
的情况下将字节隐式转换为int是Java中的一个错误源。这并不是因为“Java中的错误”隐式转换。这是由于开发者的误解。Java的字节原语只支持-128到127之间的值。如果有人试图在其中填充一个无符号值(如0xC8),它可能会与一组前导值一起滚动(由于两个补码表示法)。类似地,对于这个问题,一个完整的位空间可以有一个符号位集,数字提升也可以有类似的效果。Java实际上是在后台进行数字转换,这意味着两个操作数都转换为int原语。而不是Java中的bug,用Java编写的用户代码中的错误:)大多数程序员没有意识到字节是用Java签名的,坦率地说,他们在Java规范中将字节视为已签名的,这是一种愚蠢的默认行为,但他们这样做是为了与其他整数类型保持一致,因为它们都没有未签名的版本。同样的问题也出现在短裤到INT的转换上,因为人们通常也没有意识到短裤是有签名的。(由于值的范围非常有限,因此更容易用字节触发符号扩展错误。)但人们确实希望对int和long进行签名。
int i= rno[0];
int i= (rno[0]<<24)&0xff000000|
       (rno[1]<<16)&0x00ff0000|
       (rno[2]<< 8)&0x0000ff00|
       (rno[3]<< 0)&0x000000ff;
byte b = (byte)0xC8;
int v1 = b;       // v1 is -56 (0xFFFFFFC8)
int v2 = b & 0xFF // v2 is 200 (0x000000C8)
byte b = (byte)255;
int i = b &255;