2015-06-04 5 views
18

У меня есть пользовательский интерфейс я использую в течение некоторого времени, который выглядит примерно так:Функциональный интерфейс Наследование Куирк

public interface Function<T, R> { 
    R call(T input); 
} 

Я хотел бы модифицировать этот интерфейс с обоими в Java Function, а также гуавы-х Function , сохраняя при этом FunctionalInterface. Я думал, что идеальное расположение:

@FunctionalInterface 
public interface Function<T, R> extends 
     java.util.function.Function<T, R>, 
     com.google.common.base.Function<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

Оба суперинтерфейсов декларировать же apply() метода, который был реализован в моем интерфейсе, оставляя только абстрактные call() метод. Как ни странно, он не будет компилироваться, сообщая мне

Аннотации недействительные '@FunctionalInterface'; Функция < T, R > не функциональный интерфейс

Незнакомец по-прежнему, следующие варианты компиляции просто отлично:

@FunctionalInterface 
public interface Function<T, R> extends 
     java.util.function.Function<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

@FunctionalInterface 
public interface Function<T, R> extends 
     com.google.common.base.Function<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

public interface Function<T, R> extends 
     java.util.function.Function<T, R>, 
     com.google.common.base.Function<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

@FunctionalInterface 
public interface Function<T, R> extends 
     java.util.function.Function<T, R>, 
     com.google.common.base.Function<T, R> { 

    @Override 
    R apply(T input); 
} 

Есть ли причина, по которой первая версия не будет компилироваться?

+1

Вашего третий один компилируется, потому что вы не добавили ограничения, что оно должно быть '@ FunctionalInterface' (это аннотация подтвержден компилятором). –

+1

@SotiriosDelimanolis, очевидно. – shmosel

+5

Собираетесь ли вы с Eclipse? Компиляция отлично с компилятором Oracle. –

ответ

9

Как указано в комментариях, он компилируется с помощью компилятора oracle. Это ошибка затмения.

В ожидании исправления ошибки, лично я удалю аннотацию @FunctionalInterface (ваша третья вариация):

public interface Function<T, R> 
           extends 
            java.util.function.Function<T, R>, 
            com.google.common.base.Function<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

Основные неудобное этим решения заключается в том, что ошибка компилятора затмения предотвратить с помощью Function как lambda target type ,


Если вы действительно хотите сохранить @FunctionalInterface на вашем Function, а (некрасиво) обходной путь может быть ввести промежуточный интерфейс:

public interface AdapterFunction<T, R> 
             extends 
              java.util.function.Function<T, R>, 
              com.google.common.base.Function<T, R> { 
    @Override 
    default R apply(T input) { 
     return null; 
    } 
} 

и пусть ваш Function расширяет это AdapterFunction:

@FunctionalInterface 
public interface Function<T, R> 
           extends 
            AdapterFunction<T, R> { 

    R call(T input); 

    @Override 
    default R apply(T input) { 
     return call(input); 
    } 
} 

В этом случае Function является допустимым типом цели для затмения :

Function<String, Object> function = st -> st.toString(); 
+1

Да, я нашел аналогичный отчет об ошибке [здесь] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=453552). Меня не интересует сама аннотация; проблема в том, что он не позволит мне использовать лямбда-выражения. Я попробовал нечто похожее на вашу идею адаптера, без успеха. Завтра я попробую. – shmosel

+1

Решение с функцией «AdapterFunction» также работает в eclipse. Но удаление '@ FunctionalInterface' (3-я вариация) не – gontard

+0

Вы правы, он работает, реализует' apply() 'в адаптере. Благодаря! – shmosel

 Смежные вопросы

  • Нет связанных вопросов^_^