Java中InputSource和StreamSource的区别及不可替代场景是什么?
关于InputSource与StreamSource的差异及共存原因解答
问题梳理
我想了解InputSource的适用场景有哪些?换句话说,是否存在InputSource无法被StreamSource替代的情况?进一步说,为什么JDK中会同时存在这两个类?
已知信息:
- 二者都属于
java.xml模块,API几乎完全一致,仅有的区别是InputSource支持设置encoding参数;而StreamSource实现了Source接口属于源层级体系的一部分,在部分场景下使用更友好——设计API时可以仅要求传入Source类型参数即可满足需求。 - 二者都是在Java 1.4版本引入的。
- 两个类被应用在JDK API的不同模块中:解析器可以接收InputSource作为输入,但不支持StreamSource;Transformer可以接收StreamSource作为输入,但不支持InputSource。
核心解答
为什么两个类会同时存在
二者并非JDK重复造轮子,而是分属不同的XML处理规范体系,为了兼容不同的XML标准接口要求才同时存在:
InputSource是SAX(XML简单应用程序接口)规范定义的标准输入容器,SAX是早期社区推出的事件驱动XML解析规范,JDK集成SAX实现时自然要遵循规范引入该类,专门服务于SAX解析器、DOM原生解析器等底层XML解析组件。StreamSource是JAXP(Java XML处理API)转换规范定义的输入类型,实现了统一的Source接口,和DOMSource、SAXSource同属源层级体系,专门服务于XSLT转换、XPath处理等高层XML处理组件。
二者API相似是因为核心能力都是封装XML的输入来源(字节流、字符流、资源路径),但因为归属的技术栈不同,接口定义不兼容,所以无法互相替换使用。
InputSource不可被替代的场景
以下场景只能使用InputSource,完全无法用StreamSource替代:
- 调用SAX解析器、DOM原生解析器的
parse方法时,这类方法的入参只识别InputSource类型,传入StreamSource会直接报错。 - 自定义SAX实体解析器
EntityResolver时,接口要求的返回值类型是InputSource,用于处理DTD引用、外部实体等场景,没有替换空间。 - 需要显式指定XML编码时,直接调用
InputSource.setEncoding()即可,解析器会优先使用该编码解析,不需要手动封装InputStreamReader,比StreamSource的编码处理更直接。
各自适用场景
InputSource适用场景:- 底层XML解析(SAX、DOM原生解析)的输入传递
- 自定义实体解析逻辑的返回值封装
- 需要快速指定XML编码的解析场景
StreamSource适用场景:- XSLT转换、XML格式转换等Transformer相关处理的输入传递
- XPath查询的输入源传递
- 需要适配统一
Source接口的XML处理流水线,兼容多种源类型的场景
内容的提问来源于stack exchange,提问作者Olivier Cailloux
相关产品推荐
相关产品推荐

