Java 网络编程[Elliotte R.H.] 中对InputStream.markSupported()方法的误解
2015-11-02 16:45
537 查看
Elliotte 在书中(第四版35页,中译版42页)指出,
其实他的说法也没错,就当个类而言,这不得不说是一个非常差的设计。但是,他忽略了一点,Java的IO库使用了装饰器模式,各个IO类并非独立存在,大多数可以相互串接,以添加所需特性。
举个例子,下面的代码中,两次测试同一个变量,但结果却不尽相同。如若按照Elliotte所言,使用一个单独的接口而不是超类中的公有方法,通过
程序将打印:
这里,很明显,
Java中,输入流过滤器类都继承
而在像
如此一来,不管变量的类型如何,只要“装饰器链”中存在一个支持标记的类,
注:图片截取自[Core Java, Cay S.Horstman, Gary Cornell, 9th edition, volume 2]
后记,Elliotte 的《Java IO》一书,也同样存在此错误。笔者给他发过邮件,可惜他并没有回复。
InputStream.markSupported()方法的是一个设计上的失误,毕竟,
java.io包中,“仅有两个类始终支持标记(
BufferedInputStream和
ByteArrayInputStream)”。
其实他的说法也没错,就当个类而言,这不得不说是一个非常差的设计。但是,他忽略了一点,Java的IO库使用了装饰器模式,各个IO类并非独立存在,大多数可以相互串接,以添加所需特性。
举个例子,下面的代码中,两次测试同一个变量,但结果却不尽相同。如若按照Elliotte所言,使用一个单独的接口而不是超类中的公有方法,通过
instanceof或反射机制,我们虽然能够得知该对象的顶层类,但却无法真正得知其底层对象是否支持标记。
import java.io.*; /** * @author Jekton */ public class Tester { public static void main(String[] args) throws FileNotFoundException { InputStream in = new FileInputStream("E:\\myWorkspace\\in.txt"); InputStream decorated = new DataInputStream(in); System.out.println("markSupported() = " + decorated.markSupported()); // inputStream that has an additional decorator decorated = new DataInputStream(new BufferedInputStream(in)); System.out.println("markSupported() = " + decorated.markSupported()); System.out.println("decorated instanceof DataInputStream = " + (decorated instanceof DataInputStream)); } }
程序将打印:
markSupported() = false markSupported() = true decorated instanceof DataInputStream = true
这里,很明显,
DataInputStream并不支持标记,如果使用一个独立的接口的话,我们根本无法得知中间还有个
BufferedInputStream(这也是装饰器模式的优点之一)。更有甚者,此时的
decorated变量根本就没有
markSupported()方法。
Java中,输入流过滤器类都继承
FilterInputStream(当然,这也包括上面提到的
BufferedInputStream),
FilterInputStream重写(override)了超类
InputStream的
markSupported(), 其直接调用底层输入流的
markSupported()方法
// FilterInputStream public boolean markSupported() { return in.markSupported(); }
而在像
BufferedInputStream这一类支持标记的类中,则直接返回l
true
// BufferedInputStream public boolean markSupported() { return true; }
如此一来,不管变量的类型如何,只要“装饰器链”中存在一个支持标记的类,
markSupported()都将返回
true。
注:图片截取自[Core Java, Cay S.Horstman, Gary Cornell, 9th edition, volume 2]
后记,Elliotte 的《Java IO》一书,也同样存在此错误。笔者给他发过邮件,可惜他并没有回复。
相关文章推荐
- 华为的新突破-物联网的敏捷性开发
- HDU 4609 3-idiots
- UVA - 10881-Piotr's Ants-思路题/模拟
- 物联网核心协议—消息推送技术演进
- jaudiotagger获取MP3文件信息及封面图片
- Riot工程师:三步让你的游戏更新更快更小
- 计划继续深化学习物联网系统的相关知识 目前的WiFi模块基于ESP8266
- 谁将改变移动?--来自移动开发者大会的4个心动故事
- 一个大三的物联网专业学生的想法法
- 物联网探秘:那些来自传感器的数据都是如何上传至云端的?
- hdu 4609 3-idiots(FFT)
- 看看,这就是微软的“万物互联”系统 window10 IOT
- 看看,这就是微软的“万物互联”系统 window10 IOT
- 【物联网】OpenWrt SCP工具的使用
- 【物联网】OpenWrt编译和修改基础--预科
- Linux进程实时IO监控iotop命令详解 (系列一)
- IoTF 只认识use-token-auth
- mondrian+Jpviot页面报错
- 无锡恒和科技物联网平台
- Ubuntu会怎么玩物联网平台