我不了解有关Java Consumer界面的示例中的方法声明。我在一本在线书(Listing 11.7)中找到了这个例子。 它说:
class Consumers {
public static <T> Consumer<T> measuringConsumer( Consumer<T> block){
return t -> {
long start = System.nanoTime();
block.accept( t );
long duration = System.nanoTime() - start;
Logger.getAnonymousLogger().info("Execution time (ns): " + duration);
};
}
}
在声明中<T> Consumer<T>
是什么意思?不应该只有Consumer<T>
没有第一个<T>
?
答案 0 :(得分:4)
第一个<T>
用于定义Consumer
将接受的对象类型的边界。
在这种特殊情况下,该方法似乎接受来自java.lang.Object
的任何内容,但您可以通过执行以下操作来使用它来进一步约束可接受的类型:
public static <T extends Foo> Consumer<T> measuringConsumer(Consumer<T> block) { ... }
有关更多示例,请参阅docs。
答案 1 :(得分:2)
第一个<T>
是泛型类型变量。它表示measuringConsumer
方法是泛型,即它接受和/或返回泛型类型。
在这种情况下,该方法接受类型为Consumer<T>
的参数(泛型类型),并返回值为Consumer<T>
的值,该值也是通用的。最重要的是,返回值的泛型类型是参数的相同泛型类型。这意味着如果您传递Consumer<Integer>
作为参数,此方法将返回Consumer<Integer>
而不是Consumer<String>
,因为T
类型变量对于两者都相同参数和返回值。
请注意,类型变量T
不受限制。这意味着T
可以是任何内容,即您可以传递Consumer
任何内容作为参数,例如Consumer<Integer>
,Consumer<Double>
,Consumer<String>
,{{ 1}}等等。
如果Consumer<YourOwnClass>
有界限,即T
,那么<T extends Number>
只能是Consumer<T>
,Consumer<Integer>
,Consumer<Long>
,{{1}事实上,Consumer<BigDecimal>
的任何后代的Consumer<Double>
。