将对象转换为扩展多个接口的接口

问题描述 投票:0回答:1

Jackson 的

objectMapper.readValues(...)
返回一个
MappingIterator
类,该类同时实现
Closeable
Iterator
:

public class MappingIterator<T> implements Iterator<T>, Closeable {...}

我使用它来反序列化 JSONL,但我不希望我的方法与 Jackson 特定对象绑定,因此我创建了一个

CloseableIterator
来代替它来实现两者:

public interface CloseableIterator<T> extends Iterator<T>, Closeable {...}

我希望我的方法返回

CloseableIterator
,而不是直接暴露
MappingIterator

CloseableIterator<FooBar> readFooBars(...) {
    return objectMapper.readValues(...);
}

但是,编译器不会让我在不添加未经检查的强制转换的情况下编译它,这似乎没有必要。 有没有办法将一个对象转换为一个接口,进而扩展多个接口?

java jackson
1个回答
0
投票

不幸的是,即使通过铸造也是不可能的。转换将在运行时失败,因为返回的类型未实现您的接口,即使其方法与

MappingIterator
的方法相同。但我想到了一些解决方法。

一个选择是使用您的界面作为一种委托给 Jackson 实现的装饰器:

CloseableIterator<FooBar> readFooBars(...) {
    var iterator = objectMapper.readValues(...);

    return new CloseableIterator<>() {
        @Override
        public boolean hasNext() {
            return iterator.hasNext();
        }

        @Override
        public FooBar next() {
            return iterator.next();
        }

        @Override
        public void close() throws IOException {
            iterator.close();
        }
    };
}

(如果你有 Guava,你可以使用

ForwardingIterator
来稍微减少样板代码。)

或者,您可以返回一个多边界通用包装类封装您的迭代器:

class Wrapper<T extends Iterator<FooBar> & Closeable> {
    final T result;
    
    Wrapper(T result) {
        this.result = result;
    }
}

Wrapper<?> readFooBars(...) {
    return new Wrapper<>(objectMapper.readValues(...));
}
© www.soinside.com 2019 - 2024. All rights reserved.