2014-05-02 43 views
2

我在Netbeans 8.0中遇到了Lambda表达式的问题,并且想知道如果我做错了什么,或者Netbeans或javac编译器做错了。Netbeans中的Lambda表达式问题

我有以下代码:

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()实现SAMHandView.OnCardAddedListener,然后是HandView一个亚型,所以它应该是正确的,对不对?

+0

仍然在打牌,呃?仅供参考,没有转换的版本也不能在Eclipse中为我编译(类型推断可能不够聪明)。但是,带有强制转换的版本不会显示任何冗余警告。 – Joffrey

+0

我对你的声明有点困惑,你的代码的哪个版本确实起作用,或者不适用于哪个编译器。试着用Eclipse,Netbeans 8.0和jdk1.8.0_05的javac尝试自己,我遇到了所有这些行为的相同行为,需要一个强制转换并且不会收到关于多余演员阵容的警告。这就是我所期望的。 – Holger

回答

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

您应该尽可能多使用@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。