Java 字节原始类型在现实生活中有什么用途吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6892444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are there any real life uses for the Java byte primitive type?
提问by Thorbj?rn Ravn Andersen
For some inexplicable reason the byte
primitive type is signed in Java. This mean that valid values are -128..127 instead of the usual 0..255 range representing 8 significant bits in a byte (without a sign bit).
由于某些莫名其妙的原因,byte
原始类型是用 Java 签名的。这意味着有效值是 -128..127 而不是通常的 0..255 范围,表示一个字节中的 8 个有效位(没有符号位)。
This mean that all byte manipulation code usually does integer calculations and end up masking out the last 8 bits.
这意味着所有字节操作代码通常都会进行整数计算并最终屏蔽掉最后 8 位。
I was wondering if there is anyreal life scenario where the Java byte
primitive type fits perfectly or if it is simply a completely useless design decision?
我想知道是否有任何现实生活场景中 Javabyte
原始类型非常适合,或者它是否只是一个完全无用的设计决策?
EDIT: The sole actual use case was a single-byte placeholder for native code. In other words, not to be manipulated as a byte inside Java code.
编辑:唯一的实际用例是本机代码的单字节占位符。换句话说,在 Java 代码中不要作为字节进行操作。
EDIT: I have now seen a place where an inner tight loop needed to divide by 7 (numbers 0..32) so a lookup table could be done with bytes as the datatype so the memory usage could be kept low thinking of L1 cache usage. This does not refer to the signed/unsignedness but was a case of an actual usage.
编辑:我现在已经看到一个内部紧密循环需要除以 7(数字 0..32)的地方,因此可以使用字节作为数据类型来完成查找表,因此考虑到 L1 缓存的使用情况,可以将内存使用量保持在较低水平. 这不是指有符号/无符号,而是实际使用的情况。
采纳答案by Michael Mrozek
Amazingly, I just used byte
in Java for the first time last week, so I do have an (albeit unusual) use-case. I was writing a native Java function, which lets you implement a function in a library that can be called by Java. Java types need to be converted to types in the native language, in this case C
令人惊讶的是,我byte
上周才第一次在 Java 中使用,所以我确实有一个(尽管不寻常)用例。我正在编写一个本机 Java 函数,它可以让您在可由 Java 调用的库中实现一个函数。Java 类型需要转换为本机语言的类型,在本例中为 C
The function needed to take an array of bytes, but (forgetting about the byte
type entirely at the time) I had it take a char[]
. The signature Java generates for the C function gives the type of that parameter as jcharArray
, which can be converted to a bunch of jchar
s, which are typedef-ed in jni.h
to unsigned short
. Naturally, that is not the same size -- it's 2 bytes instead of 1. This caused all sorts of problems with the underlying code. Making the Java type byte[]
resulted in a jbyteArray
, and jbyte
on Linux is typedef-ed to signed char
, which is the right size
该函数需要接受一个字节数组,但是(当时byte
完全忘记了类型)我让它接受了一个char[]
. Java 为 C 函数生成的签名给出了该参数的类型 as jcharArray
,它可以转换为一堆jchar
s,这些 s 被 typedef-ed in jni.h
to unsigned short
。自然,这不是相同的大小——它是 2 个字节而不是 1 个。这导致了底层代码的各种问题。使 Java 类型byte[]
产生 a jbyteArray
,而jbyte
在 Linux 上是 typedef-ed to signed char
,这是正确的大小
回答by Bozho
Josh Bloch recently mentioned in a presentationthat this is one of the mistakes in the language.
Josh Bloch 最近在一次演讲中提到这是语言中的一个错误。
I think the reason behind this is that java does not have unsigned numeric types, and byte
should conform to that rule. (Note: char
is unsigned, but does not represent numbers)
我认为这背后的原因是 java 没有无符号数字类型,byte
应该符合该规则。(注:char
无符号,但不代表数字)
As for the particular question: I can't think of any example. And even if there were examples, they would be fewer than the ones for 0..255, and they could be implemented using masking (rather than the majority)
至于具体问题:我想不出任何例子。即使有示例,它们也会比 0..255 的示例少,并且可以使用掩码(而不是大多数)来实现
回答by irreputable
byte, short, char
types are mostly useless, except when used in arrays to save space.
byte, short, char
类型大多没用,除非在数组中使用以节省空间。
Neither Javaor JVMhas any real support for them. Almost all operations on them will promote them to int
or long
first. We cannot even write something like
无论是Java的或JVM对他们产生任何切实的支持。几乎所有对它们的操作都会将它们提升到int
或long
首先。我们甚至不能写这样的东西
short a=1, b=2;
a = a + b; // illegal
a = a << 1; // illegal
Then why the heck even bother with defining operations on byte, short, char
types at all?
那为什么还要费心在byte, short, char
类型上定义操作呢?
All they do are sneaking in widening conversions that will surprise the programmer.
他们所做的只是偷偷进行扩大转换,这会让程序员感到惊讶。
回答by lokori
Digitized sound (or any other signal) with 8 bit signed samples seems like the only reasonable example to me. Of course having signed bytes is no requirement to handling such signals and it can be argued whether Java byte "fits perfectly".
具有 8 位带符号样本的数字化声音(或任何其他信号)对我来说似乎是唯一合理的例子。当然,处理此类信号不需要有符号字节,并且可以争论 Java 字节是否“完全适合”。
Personally I think not having unsigned is a mistake. Not only because there's more use for unsigned bytes/ints but because I prefer a stronger type system. It would be nice to be able to specify that negative numbers are not valid and allow compiler checks and runtime exceptions for violations.
我个人认为没有签名是一个错误。不仅因为无符号字节/整数有更多用途,而且因为我更喜欢更强的类型系统。如果能够指定负数无效并允许编译器检查和运行时异常,那就太好了。
回答by Bahribayli
byte
has an extensive use in applet development for Java Card. Because cards have limited resources every bit of memory is precious. By the way card processors have limitations in processing of integer values. int
type support is optional and java.lang.String
is not supported so all integer operation and data storage is done by byte
and short
variables and arrays. As integer literals are of int
type, they should be explicitly cast to byte
or short
in whole code. Communication with card goes through APDU commands that is handed to applet as an array of byte
s that should be decomposed to byte
s to decode command class, instruction and parameters. Looking at the following code you see how much byte
and short
types are important to Java Card development:
byte
在 Java Card 的小程序开发中有着广泛的用途。由于卡的资源有限,每一位内存都很宝贵。顺便说一下,卡片处理器在处理整数值方面有局限性。int
型的支持是可选的,java.lang.String
不被支持,因此所有整数运算和数据存储是通过完成byte
和short
变量和数组。由于整数文字是int
类型的,它们应该被显式地转换为byte
或short
在整个代码中。与卡的通信通过 APDU 命令传递给小程序作为byte
s的数组,这些s 应分解为byte
s 以解码命令类、指令和参数。查看以下代码,您会看到类型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
}
回答by Ray Toal
I think it is signed in order to be consistent with short and int.
我认为它是签名的,以便与 short 和 int 保持一致。
As to whether it is used much, it makes the notion of "byte arrays" a construct rather than a primitive.
至于它是否被大量使用,它使“字节数组”的概念成为一种构造而不是一种基元。
That's really all I have. :)
这真的是我的全部。:)
回答by Bill K
On a machine with words larger than 8 bits it's somewhat useful if you wish to store a lot of values that fit in an 8-bit range into a single array, but typically it's not a good idea to use them otherwise since a byte is actually more effort to get out of memory than an int.
在字大于 8 位的机器上,如果您希望将许多适合 8 位范围的值存储到单个数组中,这在一定程度上很有用,但通常不使用它们不是一个好主意,因为一个字节实际上是比 int 更努力地摆脱内存。
Remember though that Java was designed for very small consumer devices (set-top TV boxes). I expect if it had been used this way on small 8-bit microprocessors it would have been more useful as it would fit the word size exactly and could be used for general "Math" operations on a very small scale.
请记住,Java 是为非常小的消费设备(机顶盒)设计的。我希望如果它在小型 8 位微处理器上以这种方式使用它会更有用,因为它完全适合字长并且可以用于非常小规模的一般“数学”运算。
The only reason I can see to make it signed is that an unsigned byte interacting with an int can be a little confusing--but I'm not convinced it's any more confusing than a signed one is!
我能看到使其有符号的唯一原因是与 int 交互的无符号字节可能有点令人困惑——但我不相信它比有符号的字节更令人困惑!
回答by TiwariVivek
The size of byte is 8 bits. The size of byte helps in processing input and output while performing functions like writing to a file or reading from a file. Consider a scenario in which you want to read an input from the keyboard or from any file. If you use the "byte" data structure, you know that you are receiving one character at a time since the size is 8 bits. So every time you receive an input stream, you know that you are actually receiving one character at a time.
字节大小为 8 位。字节大小有助于在执行写入文件或读取文件等功能时处理输入和输出。考虑这样一种情况,您希望从键盘或任何文件中读取输入。如果您使用“字节”数据结构,您就知道一次接收一个字符,因为大小为 8 位。因此,每次接收输入流时,您都知道实际上一次接收一个字符。
回答by Uooo
I used it frequently when I was programming software and games for J2ME. On most J2ME-devices, you have limited resources, so storing for example the map of a level in a byte-array is less resource-intensive than storing it in an int-array.
我在为 J2ME 编写软件和游戏时经常使用它。在大多数 J2ME 设备上,您的资源是有限的,因此将级别的映射存储在字节数组中比将其存储在 int 数组中占用的资源更少。
回答by user3777124
I am using bytes right now in java for a bluetooth android project.
我现在在 java 中使用字节用于蓝牙 android 项目。