Netbeans中的Lambda表达式问题

时间:2014-05-02 13:56:13

标签: java netbeans lambda java-8 netbeans-8

我在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的子类型,所以它应该是正确的,对吗?

2 个答案:

答案 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。