我们在处理完 IO 操作后,通常会在 finally 块中把打开的 IO 流资源手动关闭,以前一直用 Eclipse,今天用 IDEA 写了一个小例子,刚好写到处理流的关闭操作。IDEA 提示了我一个编码风格的问题,它认为我有两段代码重复了,代码内容如下:
public class JavaSerializer implements ISerializer {
@Override
public <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];
}
@Override
public <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 {
@Override
public <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];
}
@Override
public <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 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。