InputStream in = ...;
in b = in.read();
对InputStream的读取操作可能发生三种情况:
- 异常,抛出IOException;
- 读取到一个字节;
- 到达输入流的结尾。
其中第2种情况应该返回一个字节(Java中字节的取值范围是-128~127),第3种情况应该返回一个表示“end of file”的特殊对象(暂且叫做EofObject
)。所以read()
的返回值类型应该是Union<Byte, EofObject>
。
但是Java用int
这一种类型表示了2种情况:
- 0~225的整数表示一个字节;
- -1表示输入流的结尾。
这种做法带来了一些问题:
- -1的存在导致了read返回的字节无法直接用Java的byte类型表示,造成了空间浪费;
- 将read返回的int cast成byte前需要校验值是否为-1,忘记校验或者不小心多做了一次cast都可能引入bug。
P.S. 这里的Union应该是Typed Racket的那种“checked union”,而不是C那样的“unchecked union”。