使用序列化代理模式是不是必须使用writeObject()?

时间:2014-10-02 07:56:30

标签: java serialization

我正在为一堆我的类使用序列化代理模式,最近将FindBugs添加到我的构建过程中,现在我想知道FindBugs是否正确......

这是有问题的课程:

public class Block implements Serializable {
    private static final long serialVersionUID = 584958030434385L;

    private final float confidence;
    private final Rectangle boundingBox;
    private final Rectangle baseline;
    private final BufferedImage binaryImage;
    private final List<Paragraph> paragraphs;

    private TessResult parentTessResult;

    private Block(final float confidence, final Rectangle boundingBox, final Rectangle baseline, final BufferedImage binaryImage, final List<Paragraph> paragraphs) {
        this.confidence = confidence;
        this.boundingBox = Objects.requireNonNull(boundingBox, "boundingBox");
        this.baseline = Objects.requireNonNull(baseline, "baseline");
        this.binaryImage = binaryImage;
        this.paragraphs = Objects.requireNonNull(paragraphs, "paragraphs");
    }

    void setParentTessResult(final TessResult parentTessResult) {
        this.parentTessResult = Objects.requireNonNull(parentTessResult, "parentTessResult");
    }

    public float getConfidence() {
        return confidence;
    }

    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    public Rectangle getBaseline() {
        return baseline;
    }

    public BufferedImage getBinaryImage() {
        return binaryImage;
    }

    public List<Paragraph> getParagraphs() {
        return paragraphs;
    }

    public TessResult getParentTessResult() {
        return parentTessResult;
    }

    public static class BlockBuilder {
        private final float confidence;
        private final Rectangle boundingBox;
        private final Rectangle baseline;
        private final BufferedImage binaryImage;
        private final List<Paragraph> paragraphs = new ArrayList<>();

        public BlockBuilder(final float confidence, final Rectangle boundingBox, final Rectangle baseline, final BufferedImage binaryImage) {
            this.confidence = confidence;
            this.boundingBox = boundingBox;
            this.baseline = baseline;
            this.binaryImage = binaryImage;
        }

        public BlockBuilder addParagraph(final Paragraph paragraph) {
            paragraphs.add(Objects.requireNonNull(paragraph, "paragraph"));
            return this;
        }

        public Block build() {
            return new Block(confidence, boundingBox, baseline, binaryImage, paragraphs);
        }
    }

    private Object writeReplace() throws IOException {
        return new SerializationProxy(this);
    }

    private void readObject(final ObjectInputStream stream) throws InvalidObjectException {
        throw new InvalidObjectException("Proxy required");
    }

    private static class SerializationProxy implements Serializable {
        private static final long serialVersionUID = 12321313232553L;

        private final float confidence;
        private final Rectangle boundingBox;
        private final Rectangle baseline;
        private final byte[] binaryImageBytes;
        private final List<Paragraph> paragraphs;

        private SerializationProxy(final Block block) throws IOException {
            this.confidence = block.confidence;
            this.boundingBox = block.boundingBox;
            this.baseline = block.baseline;
            this.binaryImageBytes = bufferedImageToBytes(block.binaryImage);
            this.paragraphs = block.paragraphs;
        }

        private Object readResolve() throws IOException {
            BufferedImage binaryImage = bytesToBufferedImage(binaryImageBytes);
            Block block = new Block(confidence, boundingBox, baseline, binaryImage, paragraphs);
            for (Paragraph paragraph : paragraphs) {
                paragraph.setParentBlock(block);
            }
            return block;
        }
    }
}

需要注意的一点是它存储了BufferedImage,但在内部它将BufferedImage存储为序列化的byte[]

现在我从FindBugs收到这个警告:

  

类com.yob.dpc2.ocr.utils.data.Block定义非瞬态非可序列化实例字段binaryImage [“com.yob.dpc2.ocr.utils.data.Block”]在Block.java:[第18-95行]

所以我深入研究了这个问题,我发现我没有提供private void writeObject(ObjectOutputStream oos) throws IOException ......

所以我的问题是:我应该提供writeObject()方法吗?如果是这样,有没有办法可以重用writeReplace()方法或做其他事情来防止逻辑重复?

1 个答案:

答案 0 :(得分:2)

  

我应该提供writeObject()方法吗?

不,因为你的writeReplace()方法无法调用它。

你反对FindBugs的限制。让你的课堂成为特例。