我在Netbeans 8.0中遇到了Lambda表达式的问题,我想知道我做错了什么,或者Netbeans或javac编译器做错了。
我有以下代码:
public interface HandView extends View<Hand> {
void onCardAdded(final Card card);
void onCardPlayed(final int cardIndex);
void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo);
public static HandView merge(final HandView... handViews) {
return new HandView() {
@Override
public void onCardAdded(final Card card) {
Arrays.stream(handViews).forEach(handView -> handView.onCardAdded(card));
}
@Override
public void onCardPlayed(final int cardIndex) {
Arrays.stream(handViews).forEach(handView -> handView.onCardPlayed(cardIndex));
}
@Override
public void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo) {
Arrays.stream(handViews).forEach(handView -> handView.onCardsSwapped(cardIndexOne, cardIndexTwo));
}
};
}
@FunctionalInterface
public static interface OnCardAddedListener extends HandView, Consumer<Card> {
@Override
default void accept(final Card card) {
onCardAdded(card);
}
@Override
void onCardAdded(final Card card);
@Override
default void onCardPlayed(final int cardIndex) { }
@Override
default void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo) { }
}
@FunctionalInterface
public static interface OnCardPlayedListener extends HandView, IntConsumer {
@Override
default void accept(final int cardIndex) {
onCardPlayed(cardIndex);
}
@Override
default void onCardAdded(final Card card) { }
@Override
void onCardPlayed(final int cardIndex);
@Override
default void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo) { }
}
@FunctionalInterface
public static interface OnCardsSwappedListener extends HandView {
@Override
default void onCardAdded(final Card card) { }
@Override
default void onCardPlayed(final int cardIndex) { }
@Override
void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo);
}
}
然后我将其用于:
AtomicInteger counter = new AtomicInteger(0);
HandView handView = card -> counter.incrementAndGet();
Netbeans提供以下信息:
incompatible types: HandView is not a functional interface
multiple non-abstract methods found in interface HandView
然后我决定手动投射:
HandView handView =
(HandView.OnCardAddedListener)card -> counter.incrementAndGet();
现在它警告我演员是多余的。
当我在Netbeans 8.0中使用原始版本编译它时,它编译正常,没有任何编译(或运行时)错误。谁现在有过错?
我会说card -> counter.incrementAndGet()
实现 SAM HandView.OnCardAddedListener
,然后它是HandView
的子类型,所以它应该是正确的,对吗?
答案 0 :(得分:1)
我认为您从Netbeans收到的错误消息是正确的:
public interface HandView extends View<Hand> {
void onCardAdded(final Card card);
void onCardPlayed(final int cardIndex);
void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo);
(...)
}
这确实是不一个FunctionalInterface。
关于这一行:
HandView handView =
(HandView.OnCardAddedListener)card -> counter.incrementAndGet();
我会把它写成:
HandView.OnCardAddedListener handView = card -> counter.incrementAndGet();
我希望编译器能够更好地处理,而不会发出任何警告。
答案 1 :(得分:1)
您应该尽可能多地使用@FunctionalInterface
。
如果您注释HandView
界面
@FunctionalInterface
public interface HandView extends View<Hand> {
您将收到HandView
接口不起作用的编译错误,即。它声明了多个abstract
方法。
当你施展它时
HandView handView =
(HandView.OnCardAddedListener)card -> counter.incrementAndGet();
它应该有用。在该上下文中的lambda表达式,即。在预期HandView.OnCardAddedListener
的情况下,OnCardAddedListener
会看到@FunctionalInterface
。因此,可以从lambda表达式创建实例。
完整性的其他信息:考虑功能接口可以包含任意数量的默认或静态方法,例如参见java.util.function.Function。