2014-05-15 38 views
7

我這樣做:Lambda只能與功能界面一起使用嗎?

public class LambdaConflict 
{ 
    public static void main(String args[]){ 
     //* 
     System.out.println(LambdaConflict.get(
      (str) -> "Hello World!! By ME?" 
     )); 
     /*/ 
     System.out.println(LambdaConflict.get(new Intf<String>(){ 
      @Override public String get1(String str){ 
       return "Hello World!! By get1 " + str; 
      } 
     })); 
     /*****/ 
    } 

    public static String get(Intf<String> i, boolean b){ 
     return i.get1("from 1"); 
    } 
} 

interface Intf<T> 
{ 
    public T get1(T arg1); 

    public T get2(T arg1); 
} 

,並得到此異常:

不兼容的類型:INTF不是一個功能界面在界面中發現INTF 注 多個非壓倒一切的抽象方法:有些郵件被簡化了;與-Xdiags重新編譯:冗長獲得 全輸出 1錯誤

是否有我不能使用lambda來代替匿名類的情況?

+1

_overcome_ it是什麼意思?你明白錯誤嗎? –

+0

1)功能接口只能有1個方法。 2)他們必須註釋@FunctionalInterface –

+1

功能接口也被稱爲SAM類型(單一抽象方法類型)。所以,你的功能界面只能有一個抽象方法。 –

回答

15

不,沒有辦法「克服」這一點。功能接口只能有一個抽象方法。您的界面有兩個:

interface Intf<T> { 
    public T get1(T arg1); 
    public T get2(T arg1); 
} 

注意:您不需要註釋註釋中提到的界面。但是如果您的接口不是有效的功能接口,則可以使用@FunctionalInterface註釋來獲得編譯時錯誤。所以它爲您的代碼帶來了更多的安全性。

欲瞭解更多信息,請參閱http://java.dzone.com/articles/introduction-functional-1

+1

感謝關於'@ FunctionalInterface'的提示!我忘記它有特殊的屬性。另外,我發現從Oracle升級到最新的JDK8補丁也有助於改進錯誤消息。老版本的JDK8有時可能允許上面的代碼進行編譯,但在運行時會失敗,並帶有'java.lang.AbstractMethodError'。較新的版本將在編譯時被拒絕。 – kevinarpe

1

想想看:

  • 應該如何編譯器知道,如果你想覆蓋get1get2

  • 如果您只覆蓋get1,那麼get2的實現是什麼?即使你註釋掉了,因爲你沒有實現get2將無法​​正常工作的代碼...

是有原因的此限制...

0

如前所述通過@托馬斯 - UHRIG,功能接口只能有一種方法

來解決這個問題,主要是因爲你從來不使用public T get2(T arg1);的一種方式,是改變Intf<T>接口:

@FunctionalInterface 
interface Intf<T> 
{ 
    public T get1(T arg1); 
} 
6

僅供參考,以豐富已經給出了答案:

JSR-335: Lambda Expressions for the Java Programming Language在章節Lambda Specification,Part A:Functional Interfaces中說:

功能接口是一個接口ace只有一個摘要 方法(除了Object的方法),因此代表一個 單功能合同。 (在某些情況下,這種「單一」方法可能採用多個抽象方法的形式,具有從超接口繼承的替代等效 簽名;在這種情況下,繼承的 方法在邏輯上代表單個方法。)

所以,你需要的是爲你的一個方法提供一個默認的實現,或者把你的一個方法放在不同的接口中。