我们在处理完 IO 操作后,通常会在 finally 块中把打开的 IO 流资源手动关闭,以前一直用 Eclipse,今天用 IDEA 写了一个小例子,刚好写到处理流的关闭操作。IDEA 提示了我一个编码风格的问题,它认为我有两段代码重复了,代码内容如下:
public class JavaSerializer implements ISerializer {@Overridepublic <T> byte[] serialize(T obj) {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(baos);oos.writeObject(obj);return baos.toByteArray();} catch (IOException e) {e.printStackTrace();} finally {if (oos != null) {try {oos.close();} catch (IOException e) {e.printStackTrace();}}if (baos != null) {try {baos.close();} catch (IOException e) {e.printStackTrace();}}}return new byte[0];}@Overridepublic <T> T deserialize(byte[] data, Class<T> clazz) {ByteArrayInputStream bais = new ByteArrayInputStream(data);ObjectInputStream ois = null;try {ois = new ObjectInputStream(bais);return (T) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(ois != null) {try {ois.close();} catch (IOException e) {e.printStackTrace();}}if(bais != null) {try {bais.close();} catch (IOException e) {e.printStackTrace();}}}return null;}}

IDEA 认为我上下这两段代码重复了。我觉得比较奇怪,确实两段代码都是处理 IO 流的关闭,写法也一样,但是我关闭的是不同的 IO 流资源啊,上面是关闭 ByteArrayOutputStream 和 ObjectOutputStream 这两个流的资源,下面是关闭 ByteArrayInputStream 和 ObjectInputStream 这两个流的资源,不能说代码是完全重复的吧,但是 IDEA 就给我提示了。
这两处的提示比较碍眼,本来想在 IDEA 中关闭重复代码提示得了,也不用操心这类问题,突然比较好奇有没有什么好办法统一处理这个重复问题,是否能提炼一个公共的方法?
琢磨了一会,这四个 IO 操作类是不同的类型,怎么能提炼呢?提供一个思路,我们想办法找找他们的交集,是不是有一个共用的继承类或者接口,并且这个共用类或者接口要有 close() 方法,否则也是白搭。
我们来看下这四个类的类图,找找他们的继承体系,所幸的是 IDEA 可以看类图结构,非常方便:

猜测 Closeable 接口好像可以满足要求,我们进去看看该接口的内容:

- 满足是这四个 IO 操作类的共用接口的条件。
 - 满足需要提供 close() 方法的条件。
 
接下来就是提炼一个公共的方法,代码结构如下:
public class JavaSerializer implements ISerializer {@Overridepublic <T> byte[] serialize(T obj) {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(baos);oos.writeObject(obj);return baos.toByteArray();} catch (IOException e) {e.printStackTrace();} finally {close(oos, baos);}return new byte[0];}@Overridepublic <T> T deserialize(byte[] data, Class<T> clazz) {ByteArrayInputStream bais = new ByteArrayInputStream(data);ObjectInputStream ois = null;try {ois = new ObjectInputStream(bais);return (T) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {close(ois, bais);}return null;}/*** 关闭 IO 资源** @param closeables IO 资源*/private void close(Closeable... closeables) {for (Closeable closeable : closeables) {if (closeable != null) {try {closeable.close();} catch (IOException e) {e.printStackTrace();}}}}}
这样 IDEA 就不会再提示了,整个类的代码量也压缩了一点,代码结构也清晰了一些。
作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/gwhiom 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
