Java: BufferedOutputStream里的write(int b)如何理解?

源码如下:

public synchronized void write(int b) throws IOException {
    if (count >= buf.length) {
        flushBuffer();
    }
    buf[count++] = (byte)b;
}

为何写字节要用int类型? int是四个字节,byte是一个字节,为何(byte)b?

阅读 3.1k
3 个回答

根据这篇博文来看

1个字节占8位,既然实际返回的是byte类型的数据,那么强制类型转换int型截取低8位,对数据也不会造成影响。
这是因为在int强制转换为byte型数据时,会产生一个-128~127的有符号字节,而不是read方法返回的0~255的无符号字节。

个人不负责任猜测应该是为了写入有符号字节。

因为

System.out.println((byte) 128); // 输出 -128

之所以write的参数类型是int,是因为read的返回值是int类型。而读和写通常会结合在一起来使用,比如从网络流中读取数据,写入磁盘文件。因此保持读写接口的统一是很重要的,否则读出来之后还要手动转换一下才能写入,使用起来就会很麻烦。

那么为什么read返回的是int而不是byte呢?

这是因为byte0~255不足以表示read的所有可能的返回值。因为除了正常字节之外,read还需要用其他值来表示读取异常情况,最典型的就是读到了流的末尾的时候需要返回-1。所以read需要更大范围的类型来表示其返回值。

希望这个回答能帮到你。

估计设计这个api的作者也是很纠结吧,虽然参数是int型的,但注释也说只是写入特定的字节,命名成b也是这个原因。主要是考虑后续使用的方便吧,你把byte转成int,直接写就可以`int a=b,但反过来得写成byte b=(byte)a`,很烦不是。还有就是如果你有个方法 f接受字节型参数,但`f(b1 & b2)` 却不能这么写,虽然你知道结果是字节,但编译器却认为是int,(因为+,-,*等运算结果可能是int?),所以要写成`f((byte)b1 & b2)`才行。很怪不是。

这么定义接口:

public void write(int b)

       throws IOException 

Writes the specified byte to this buffered output stream.

这还是源于OutputStream的接口设计, 只有低8位的写入,其余24位全忽略。

 public abstract class OutputStream implements{
     public abstract void write(int b) throws IOException;
...

对应InputStream的recieve方法也是接受int类型的参数。

你也可以看看这里

https://stackoverflow.com/que...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题