出于某种莫名其妙的原因,byte
基元类型是用Java签名的。这意味着有效值为-128..127而不是通常的0..255范围,表示一个字节中的8个有效位(没有符号位)。
这意味着所有字节操作代码通常都会进行整数计算,最后屏蔽最后8位。
我想知道是否存在任何现实生活场景,其中Java byte
基元类型完全适合,或者它只是一个完全无用的设计决策?
编辑:唯一的实际用例是本机代码的单字节占位符。换句话说,不要将其作为Java代码中的字节进行操作。
答案 0 :(得分:33)
Josh Bloch最近mentioned in a presentation这是该语言中的错误之一。
我认为这背后的原因是java没有无符号数字类型,byte
应符合该规则。 (注意:char
是无符号的,但不代表数字)
至于具体问题:我想不出任何一个例子。即使有例子,它们也会少于0..255的那些,并且它们可以使用掩蔽(而不是大多数)来实现
答案 1 :(得分:16)
byte, short, char
类型几乎没用,除非在数组中使用以节省空间。
Java 或 JVM 都没有真正支持它们。几乎所有关于它们的操作都会首先将它们提升到int
或long
。我们甚至不能写像
short a=1, b=2;
a = a + b; // illegal
a = a << 1; // illegal
那么为什么要对byte, short, char
类型的操作进行定义呢?
他们所做的只是偷偷摸摸地扩大转换程序,这会让程序员感到惊讶。
答案 2 :(得分:10)
令人惊讶的是,我上周第一次在Java中使用了byte
,所以我确实有一个(虽然不寻常)用例。我正在编写一个native Java function,它允许您在可以由Java调用的库中实现一个函数。需要将Java类型转换为本机语言的类型,在本例中为C
获取字节数组所需的函数,但是(当时完全忘记byte
类型)我需要char[]
。为C函数生成的签名Java将该参数的类型赋予jcharArray
,可以将其转换为一堆jchar
s,这些jni.h
在unsigned short
到{{{ 1}}。当然,这不是相同的大小 - 它是2个字节而不是1.这导致了底层代码的各种问题。使Java类型byte[]
产生jbyteArray
,并且Linux上的jbyte
被类型定义为signed char
,这是正确的大小
答案 3 :(得分:4)
带有8位带符号样本的数字化声音(或任何其他信号)似乎是我唯一合理的例子。当然,签名字节不需要处理这些信号,可以说Java字节是否“完全适合”。
我个人认为没有签名是不对的。不仅因为对无符号字节/整数的使用更多,而且因为我更喜欢更强大的类型系统。能够指定负数无效并允许编译器检查和违规的运行时异常会很好。
答案 4 :(得分:3)
byte
在Java Card的applet开发中有广泛的用途。因为卡片资源有限,所以每一点内存都是宝贵的。顺便说一句,卡处理器在处理整数值方面存在局限性。 int
类型支持是可选的,不支持java.lang.String
,因此所有整数操作和数据存储都由byte
和short
变量和数组完成。由于整数文字属于int
类型,因此应在整个代码中将它们显式转换为byte
或short
。与卡的通信通过APDU命令传递给applet,作为byte
的数组,应该分解为byte
以解码命令类,指令和参数。查看以下代码,您会看到有多少byte
和short
类型对Java Card开发很重要:
package somepackage.SomeApplet;
import javacard.framework.*;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class SomeApplet extends Applet {
// Card status
private final static byte ST_UNINITIALIZED = (byte) 0x01;
private final static byte ST_INITIALIZED = (byte) 0x02;
// Instructions & Classes
private final static byte PROP_CLASS = (byte) 0x80;
private final static byte INS_INIT_UPDATE = (byte) 0x50;
private final static byte INS_EXT_AUTH = (byte) 0x82;
private final static byte INS_PUT_DATA = (byte) 0xDA;
private final static byte INS_GET_RESPONSE = (byte) 0xC0;
private final static byte INS_GET_DATA = (byte) 0xCA;
private final static short SW_CARD_NOT_INITIALIZED = (short) 0x9101;
private final static short SW_CARD_ALREADY_INITIALIZED = (short) 0x9102;
private final static byte OFFSET_SENT = 0x00;
private final static byte OFFSET_RECV = 0x01;
private static short[] offset;
private static byte[] fileBuffer;
private static short fileSize = 0;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SomeApplet( bArray, bOffset, bLength);
}
public RECSApplet(byte[] bArray, short bOffset, byte bLength) {
offset = JCSystem.makeTransientShortArray((short) 2, JCSystem.CLEAR_ON_RESET);
fileBuffer = new byte[FILE_SIZE];
byte aidLen = bArray[bOffset];
if (aidLen== (byte)0){
register();
} else {
register(bArray, (short)(bOffset+1), aidLen);
}
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short len = apdu.setIncomingAndReceive();
byte cla = buffer[ISO7816.OFFSET_CLA];
byte ins = buffer[ISO7816.OFFSET_INS];
short lc = (short) (buffer[ISO7816.OFFSET_LC] & 0x00ff);
while (len < lc) {
len += apdu.receiveBytes(len);
}
SecureChannel sc = GPSystem.getSecureChannel();
if ((short)(cla & (short)0x80) == ISO7816.CLA_ISO7816) {
switch (ins) {
case INS_PUT_DATA:
putData(buffer, ISO7816.OFFSET_CDATA, offset[OFFSET_RECV], len);
if ((cla & 0x10) != 0x00) {
offset[OFFSET_RECV] += len;
} else {
fileSize = (short) (offset[OFFSET_RECV] + len);
offset[OFFSET_RECV] = 0;
}
return;
case INS_GET_DATA:
case INS_GET_RESPONSE:
sendData(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
else if ((byte) (cla & PROP_CLASS) == PROP_CLASS) {
switch (ins) {
case INS_INIT_UPDATE:
case INS_EXT_AUTH:
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, sc.processSecurity(apdu));
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} else
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
// Some code omitted
}
答案 5 :(得分:1)
我认为它是签名的,以便与short和int保持一致。
关于它是否被大量使用,它使“字节数组”的概念成为构造而不是原语。
这就是我的全部。 :)
答案 6 :(得分:1)
在一个字大于8位的机器上,如果你希望将大量适合8位范围的值存储到单个数组中,它会有所帮助,但通常情况下使用它们并不是一个好主意,因为byte实际上是比int更加努力的内存。
请记住,Java是专为非常小的消费设备(机顶盒电视盒)而设计的。我希望如果它在小型8位微处理器上以这种方式使用它会更有用,因为它可以精确地适应字大小,并且可以用于非常小规模的一般“数学”操作。
我能看到让它签名的唯一原因是与int交互的无符号字节可能有点令人困惑 - 但我不相信它比签名的更令人困惑!
答案 7 :(得分:0)
字节大小为8位。字节大小有助于处理输入和输出,同时执行写入文件或从文件读取等功能。考虑一种情况,您希望从键盘或任何文件中读取输入。如果你使用&#34;字节&#34;数据结构,你知道你一次收到一个字符,因为大小是8位。因此,每次收到输入流时,您都知道您实际上一次只接收一个字符。
答案 8 :(得分:-1)
当我为J2ME编写软件和游戏时,我经常使用它。在大多数J2ME设备上,您的资源有限,因此在字节数组中存储级别的映射比将数据存储在int数组中要少得多。
答案 9 :(得分:-3)
我现在正在java中使用字节用于蓝牙android项目。