只读的 SettableFuture 参考

Read-only SettableFuture reference

说一个API方法returns ListenableFuture<T>,return值被实现为SettableFuture<T>。有没有办法 return 一个不能被转换回 SettableFuture 并由行为不端的客户端完成的“ListenableFuture”?

因此,ListenableFuture 的只读视图。类似于用 .unmodifiableCollection.

包装集合

装饰器模式是实现此目的的一种广泛使用的设计模式。 可能值得看看 Guava 的作者是如何设计他们所谓的 forwarding future 来满足这类需求的。

例如,这里是从摘要中提取的一些代码 class ForwardingListenableFuture:

/**
 * A {@link ListenableFuture} which forwards all its method calls to another
 * future. Subclasses should override one or more methods to modify the behavior
 * of the backing future as desired per the <a
 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
 *
 * <p>Most subclasses can just use {@link SimpleForwardingListenableFuture}.
 *
 * @param <V> The result type returned by this Future's {@code get} method
 * 
 * @author Shardul Deo
 * @since 4.0
 */
public abstract class ForwardingListenableFuture<V> extends ForwardingFuture<V> implements ListenableFuture<V> {

  /** Constructor for use by subclasses. */
  protected ForwardingListenableFuture() {}

  @Override
  protected abstract ListenableFuture<V> delegate();

  @Override
  public void addListener(Runnable listener, Executor exec) {
    delegate().addListener(listener, exec);
  }
  ...

如你所见,这个 class 的职责是包装一个 ListenableFuture 并将其实际实现隐藏到客户端 - 包括最终用户和实现者,正如我们可以看到 delegate() 方法 returns 一个 ListenableFuture 而不是具体类型。

实际 创建 您希望隐藏的 ListenableFuture 对象的代码需要使用 [=11] 的实现来包装或 "decorates" 它=],这将阻止客户端调用 set 包装的未来。正如 javadoc 所建议的,subclassing SimpleForwardingListenableFuture 将完成这项工作,而不会对委托的方法引入潜在的副作用。

最简单的方法大概是:

return Futures.transform(future, x -> x);

请注意,从人们可以 cancel 的意义上说,未来仍然是 "writable"。如果你想阻止用户甚至取消原来的未来——我认为你不关心这个,但我还是想提出来,因为你说 "read-only"——那么你可以使用:

return Futures.nonCancellationPropagating(future);