让我们看看下面的代码,那么你可以看到为什么?
class IntegerConsumer implements Consumer<Integer>, IntConsumer {
...
}
任何类都可以实现多接口,一个是实现另一个是。有时当我们想要适应并保存其原始类型()时,会发生这种情况,然后代码如下所示:Consumer<Integer>
IntConsumer
IntConsumer
Consumer<Integer>
IntConsumer
class IntConsumerAdapter implements Consumer<Integer>, IntConsumer {
@Override
public void accept(Integer value) {
accept(value.intValue());
}
@Override
public void accept(int value) {
// todo
}
}
注意:这是类适配器设计模式的用法。
然后,您可以同时使用 as 和 ,例如:IntConsumerAdapter
Consumer<Integer>
IntConsumer
Consumer<? extends Integer> consumer1 = new IntConsumerAdapter();
IntConsumer consumer2 = new IntConsumerAdapter();
Sink.OfInt
是 jdk-8 中类适配器设计模式的具体用法。缺点显然是JVM在接受值时会抛出一个,所以这就是为什么包是可见的。Sink.OfInt#accept(Integer)
NullPointerException
null
Sink
189 interface OfInt extends Sink<Integer>, IntConsumer {
190 @Override
191 void accept(int value);
193 @Override
194 default void accept(Integer i) {
195 if (Tripwire.ENABLED)
196 Tripwire.trip(getClass(), "{0} calling Sink.OfInt.accept(Integer)");
197 accept(i.intValue());
198 }
199 }
我发现为什么需要将一个投射到一个如果传递一个消费者,就像?Consumer<Integer>
IntConsumer
IntConsumerAdapter
一个原因是当我们使用 a 来接受一个编译器需要自动将其装箱到 .在您需要手动拆箱的方法中。换句话说,每个操作都执行 2 个额外的装箱/拆箱操作。它需要提高性能,因此它会在算法库中进行一些特殊检查。Consumer
int
Integer
accept(Integer)
Integer
int
accept(Integer)
另一个原因是重用一段代码。OfInt#forEachRemaining(Consumer) 的主体是应用 Adapter Design Pattern 重用 OfInt#forEachRenaming(IntConsumer) 的一个很好的例子。
default void forEachRemaining(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
// action's implementation is an example of Class Adapter Design Pattern
// |
forEachRemaining((IntConsumer) action);
}
else {
// method reference expression is an example of Object Adapter Design Pattern
// |
forEachRemaining((IntConsumer) action::accept);
}
}