read()负责读取字符并返回int型码点或-1结束信号,==适用于基本类型比较;分水岭在于区分原始数据(用==)与对象封装(用equals),而非机制冲突。

Reader.read()干的是什么
它从输入源(如文件、网络流、字符串)中读取一个字符(int类型,范围0–65535),返回实际读到的Unicode码点;读到末尾返回-1。这个-1是约定的“结束信号”,不是真实字符。
关键点:
- read()是阻塞式同步调用,依赖底层操作系统read系统调用或缓冲策略
- 返回值类型是int,不是char——为容纳-1而设计
- 它不涉及对象地址或内容比较,纯粹是数据搬运动作
==在read场景中常被误用的地方
开发者常写:if (ch == -1) 判断流结束。这本身没错,因为-1是int字面量,ch也是int,属于基本类型比较,==完全适用。
但陷阱出现在混淆类型时:
- 若把ch误声明为Character(包装类),ch == -1 就触发自动拆箱,仍可工作;但若ch为null,会抛NullPointerException
- 若用ch.equals(-1),编译直接失败(int不能调用equals),或ch是Character时,-1会被装箱为Integer,类型不匹配导致永远返回false
真正需要警惕的“分水岭”是类型与语义边界
不是read()和==谁先谁后的问题,而是:
- 当操作的是基本类型值(如int ch = reader.read()),==安全、高效、本意即如此
- 当操作的是对象引用(如String line = bufferedReader.readLine()),就该用equals判断内容,而非==判地址
- read()返回的-1是协议值,不是对象,不进常量池,不参与引用比较逻辑
一句话总结
read()负责取数,==负责比数——两者在int层面天然契合;所谓“分水岭”,其实是开发者是否清楚自己当前处理的是原始数据还是对象封装。跨过这条线,错的不是代码,是建模意识。

















