在这种情况下,对super的更多惯用用法是什么?

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

我为维护一个Class es和可以接受这些类的实例的处理程序而注册的库,想想Consumer<T>。有一种设施可以为*类型及其所有子类型注册处理程序,例如

<T> void registerHandler(Class<T> type, Consumer<? super T>) { ... }

此外,有一种方法可以接收给定类型的相应处理程序:

<T> Consumer<T> getHandler(Class<? extends T> type)

现在我可以注册这样的处理程序:

Consumer<Object> printer = System.out::println;
registerHandler(Object.class, printer);
Consumer<String> screamer = s -> System.out.println(s.toUpperCase());
registerHandler(String.class, screamer);

检索处理程序也适用于子类型:

getHandler(Object.class) // => printer
getHandler(String.class) // => screamer
getHandler(Integer.class) // => printer, because Integer is a subtype of Object

我的问题是关于getHandler方法,特别是它对通配符类型的使用。我看到了另外两种有效的使用方式:

<T> Consumer<T> getHandler(Class<? extends T> type) // option 1, from above
<T> Consumer<? super T> getHandler(Class<T> type) // option 2
<T> Consumer<? super T> getHandler(Class<? extends T> type) // option 3
// <T> Consumer<T> getHandler(Class<T> type) // non-option, does not work for subtypes.

哪种是表示类型之间这种关系的最佳方法?

我发现使用Class<? extends T>的一个优点是可以进行以下工作:

void handle(T obj, Class<? extends T> type) {
   Consumer<? super Object> handler = getHandler(type);
   // or Consumer<Object>, depending on whether ? super is in the return type or not
   handler.accept(obj);
}

Object o = ...;
handle(o, o.getClass());

没有? extends T,在getHandler中对handle的调用将是无效的,除非它也使用Class<T>,在这种情况下,对getClass的调用将是无效的。

java generics bounded-wildcard
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.