让我们看看下面的代码,那么你可以看到为什么?
class IntegerConsumer implements Consumer, IntConsumer {
...
}
任何类都可以实现多接口,一个是Consumer< Integer>也许实现另一个是IntConsumer。当我们想要将IntConsumer适应消费者时,有时会发生这种情况。并保存其原始类型(IntConsumer),然后代码如下所示:
class IntConsumerAdapter implements Consumer, IntConsumer {
@Override
public void accept(Integer value) {
accept(value.intValue());
}
@Override
public void accept(int value) {
// todo
}
}
那么你可以使用IntConsumerAdapter作为Consumer< Integer>和IntConsumer,例如:
Consumer extends Integer> consumer1 = new IntConsumerAdapter();
IntConsumer consumer2 = new IntConsumerAdapter();
Sink.OfInt是jdk-8中Class Adapter Design Pattern的具体用法.Sink.OfInt #incept(Integer)的缺点显然是JVM在接受空值时会抛出NullPointerException,这就是Sink是包可见的原因。
07002 interface OfInt extends 07003<07004>, 07005 {
07006 @07007
07008 void accept(int value);
07009 @07007
070011 default void accept(07004 i) {
070013 if (Tripwire.ENABLED)
070014 Tripwire.070015(070016(), "{0} calling Sink.OfInt.accept(Integer)");
070017 070018(i.070019());
070020 }
070021 }
我发现为什么需要投射一个Consumer< Integer>如果传递像IntConsumerAdapter这样的消费者,那么对于IntConsumer?
一个原因是当我们使用Consumer接受一个int时,编译器需要将它自动装箱到一个Integer。在方法accept(Integer)中,您需要手动将整数解包为int。
换句话说,每个accept(整数)为装箱/拆箱做了2个额外的操作。它需要提高性能,以便在算法库中进行一些特殊检查。
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);
}
}