为什么Java OutputStream.write()采用整数但写入字节

ZZ *_*der 30 java io outputstream

我正在编写一个OutputStream,只是在OutputStream接口中注意到了这一点,

   public abstract void write(int b) throws IOException;
Run Code Online (Sandbox Code Playgroud)

这个调用会向流写一个字节,但为什么它将整数作为参数?

小智 26

所以你可以发出EOF信号:

"请注意,read()返回一个int值.如果输入是一个字节流,为什么read()不返回一个字节值?使用int作为返回类型允许read()使用-1来表示它已经到了流的末尾."

http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html

  • 所以,如果你写(-1),会发生什么?它关闭了流吗?:-) (7认同)
  • 换句话说,`write(int)`用于与`read()`对称.当你想到它时,那并不是那么糟糕.好答案. (5认同)

Bil*_*l K 10

实际上我最近一直在处理字节,它们可能很烦人.它们在最轻微的挑衅时上转换为整数,并且没有指定将数字转换为字节 - 例如,8l将为您提供长值8,但对于字节,您必须说(字节)8

除此之外,它们(几乎)将始终作为整数存储在内部,除非您使用的是数组(甚至可能......但不确定).

我认为他们只是假设使用字节的唯一原因是实际需要8位的i/o,但在内部他们希望你总是使用整数.

顺便说一句,一个字节可以执行得更糟,因为它总是必须被掩盖...

至少我记得几年前的阅读,现在可能已经改变了.

作为您特定问题的示例答案,如果函数(f)占用一个字节,并且您有两个字节(b1和b2),则:

f(b1 & b2)
Run Code Online (Sandbox Code Playgroud)

不起作用,因为b1和b2将被上转换为int,并且int无法自动下转换(精度损失).所以你必须编码:

f( (byte)(b1 & b2) )
Run Code Online (Sandbox Code Playgroud)

这会让人恼火.

并且不要问为什么b1和b2上升 - 我最近一直在讨论这个问题!

  • <begin rant> amen - Java中的字节操作充满了这样的坑洼(通常是在设计时几乎不可能捕获的类型).为什么在世界上不能编译器弄清楚新的byte [] {0x01,0x02}是一个字节数组?为什么我要写新的byte [] {(byte)0x01,(byte)0x02}?<结束咆哮> (5认同)

Atm*_*ons 7

根据OutputStream的 javadoc,此函数忽略24个高位.我认为该方法存在兼容性原因:因此您不需要先转换为字节,您只需传递一个整数即可.

问候

  • 我认为Atmocreations建议`write(int)`旨在使用户不必进行显式转换.就个人而言,我认为我宁愿让合同成为"写(字节)",而不必阅读文档就知道3/4的位被忽略了.*耸肩* (5认同)
  • 但是与什么兼容? (2认同)