Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么ByteArrayOutputStream使用int?_Java - Fatal编程技术网

Java 为什么ByteArrayOutputStream使用int?

Java 为什么ByteArrayOutputStream使用int?,java,Java,也许有人能帮我理解,因为我觉得我遗漏了一些可能会影响我的程序运行的东西 我正在使用ByteArrayOutputStream。除非我遗漏了一些重要的内容,否则这个类的重点是创建一个byte[]数组以供其他用途 然而,BAOS上的“普通”写函数采用int而不是byte() 根据this()页,在Java中,int是32位数据类型,byte是8位数据类型 如果我写这个代码 int i = 32; byte b = i; 我得到一个关于可能有损转换的警告,需要对此进行更改 int i = 32; b

也许有人能帮我理解,因为我觉得我遗漏了一些可能会影响我的程序运行的东西

我正在使用ByteArrayOutputStream。除非我遗漏了一些重要的内容,否则这个类的重点是创建一个byte[]数组以供其他用途

然而,BAOS上的“普通”写函数采用int而不是byte()

根据this()页,在Java中,int是32位数据类型,byte是8位数据类型

如果我写这个代码

int i = 32;
byte b = i;
我得到一个关于可能有损转换的警告,需要对此进行更改

int i = 32;
byte b = (byte)i;

我真的对写入(int)感到困惑。

为了方便在
0x7F
上面使用无符号字节,这会发生。int将被静默地缩小以写入。事实上,使用
(字节)
强制转换的代码

正如国际非政府组织所说:


一个可能的原因可能是,要写入的字节通常是某些操作的结果,这些操作会自动将其操作数转换为int[,如]某些位操作。因此,代码中充斥着对字节的强制转换,这对理解没有任何帮助


ByteArrayOutputStream
正在重写
OutputStream
中声明的抽象方法。所以真正的问题是,当它声明的目标是向流中写入一个字节时,为什么会这样声明。流的实现与此无关

你的直觉是正确的——在我看来,这是一个破碎的设计。是的,它将丢失数据,正如文档中明确指出的:

要写入的字节是参数b的八个低位。忽略b的24个高阶位

(在我看来)如果这是
write(byte)
,那就更明智了。唯一的缺点是,在没有强制转换的情况下,无法使用文本值调用它:

// Write a single byte 0. Works with current code, wouldn't work if the parameter
// were byte.
stream.write(0);
这看起来不错,但事实并非如此——因为文本0的类型是
int
,它不能隐式转换为
byte
。您必须使用:

// Ugly, but would have been okay with write(byte).
stream.write((byte) 0);

对我来说,这还不足以成为按原样设计API的理由,但这正是我们从Java1.0开始就有的东西。不幸的是,如果没有一个突破性的改变,现在就无法修复它。

这主要是因为Java虚拟机模型的堆栈讨厌
字节,但喜欢
int
堆栈使用32位插槽,与
int
的大小相匹配

但是,您会注意到,java*确实*像
byte[]
引用。但这是因为数组的内容存储在堆(而不是堆栈)中。每当一个特定的
字节
被寻址并移动到堆栈(bipush
sipush
操作码)时,它们会立即转换为整数

但有时java实际上使用257(!)值。当
InputStream#read()
返回256个值时,但当它没有内容时,将返回
-1
值。或者,也可以抛出一个
EOFException
(就像其他一些方法一样),但java中的异常速度很慢


尽管您不需要为
输出流#write
使用
-1
值,但它是一致的,并且减少了强制转换。但是,是的,它也是错误的。

但是,我们一点也不清楚为什么它不可能是一个
字节
参数-调用方可以很容易地进行转换,如果他们想…@JonSkeet Java API中的许多设计决策都是如此,以至于很难找到背后的合理原因。事实上,该方法接受一个int,并在其中进行显式转换。这就是what的事实,但问题是为什么。我同意在这里很难找到原因——但这只是意味着我们不知道所问问题的答案……一个可能的原因可能是,要写入的字节通常是自动将其操作数转换为
int
的某个操作的结果。比如一些位操作。因此,代码中到处都是对
字节的强制转换,这对理解没有任何帮助。可以说,如果Java是今天发明的,那么最好只在后跟[]时才允许使用byte和short,并保持所有方法签名都没有byte和short。@Ingo:我想说这确实使代码更清晰,因为这表明您只编写了一个字节,而不是整个整数。如果您的计算结果是
int
,并且您调用
write(value)
,那么不可能立即删除四分之三的潜在数据……请注意,决定这一点的是
OutputStream.write
,不是真正的
ByteArrayOutputStream
。是的,ByteArrayOutputStream很难做到这一点,但是它的父类却做到了。除了以
byte[]
的形式之外,使用
byte
数据类型可以说是个坏主意。这同样适用于
short
,IMHO。把byte和short看作是一种必要的邪恶,它只适合让您读写奇怪的二进制数据格式。不要使用字节/短变量、方法参数或返回类型。(不,您不会以任何实质性的方式节省空间(除非在罕见的情况下),而且您的代码实际上可能会更慢。)感谢所有的讨论。我很好奇,即使我的大脑有点紧张,但我的动机和避免使用许多其他功能的做法还是有意义的。我正在使用BAS为我自己的内部VM生成自定义字节码,因此我还想确认我没有编写固有的错误。Java中的字节是有符号的,因此如果该方法将
byte
作为参数,我们无法执行
stream.write(0xFF)
并获得预期的全字节。现在,为什么java不支持无符号字节…@JoshuaTaylor java实际上支持解释整数类型直到i