2016-12-04 11 views
2

비 무효인지 여부에 따라 다를 오버로드 된 메서드는 "모호한"경고 :회피 javac의 유일한 매개 변수 (λ)이 무효 또는 내가 (다른 사람의 사이에서) 다음 방법과 유틸리티 클래스 쓰고 있어요

class FunctionNamingUtils { 
    public static <T> Consumer<T> named(String name, Consumer<T> delegate) { 
     class NamedConsumer implements Consumer<T> { 
      @Override public void accept(T t) { delegate.accept(t); } 
      @Override public String toString() { return name; } 
     } 
     return new NamedConsumer(); 
    } 

    public static <T, R> Function<T, R> named(String name, Function<T, R> delegate) { 
     class NamedFunction implements Function<T, R> { 
      @Override public R apply(T t) { return delegate.apply(t); } 
      @Override public String toString() { return name; } 
     } 
     return new NamedFunction(); 
    } 
} 

컴파일러를

경고 : 자바 : 가에서 (java.lang.String의, java.util.function.Consumer) ... 이름 이름 (java.lang.String의, 자바 잠재적으로 모호한 입니다으로 뿌려줍니다. util.function.Function) ...

람다가 값을 반환하는지 void인지 여부에 따라 우리는 한 방향 으로든 다른 방향 으로든 갈 것이고,보기 힘든 단일 명령문 람다에 대해서 경고의 목적을 알 수 있습니다.

이 경우 그 것은 정확히 우리가 원하는 것이며 동일한 기능에 대해 두 가지 메서드 이름을 기억해야하는인지 부담을 줄이기 위해 오버로드를 사용하고 싶습니다. (나는 이미 타협해야했습니다. 부울 함수와 충돌하는 namedPredicate).

경고를 표시하지 않거나 다른 방식으로 API를 표현하는 것에 대한 아이디어를 찾고 있습니다. 초점은 클라이언트 측에서 명확성과 사용의 용이성에 있습니다.

Java 8 이상 만 신경 씁니다.

+3

어쨌든 namedPredicate로 이미 손상된 경우 namedFunction 및 namedConsumer도 사용하면 API의 일관성이 향상됩니다. –

+0

나는 JB에 동의한다. 물론 이것은 스타일의 문제이지만, 나는 종종 ** 과부하 ** 메소드가 ** 두뇌에 과부하 **하는 경향이 있음을 알게됩니다. 예를 들어, 이와 같은 시나리오 때문입니다. 그래서 제 2 센트도 될 것입니다. 단지 다른 이름을 사용하십시오. – GhostCat

+0

간결함은 특히 원시 개념의 경우에도 중요합니다. 그렇지 않으면 스프링 프레임 워크와 같은 이름을 갖게됩니다 (불쾌감은 없지만 유틸리티에 대해서는 좋은 선택이라고 생각하지 않습니다). – ddimitrov

답변

0

실제로 람다에 대한 나의 이해는 불완전합니다. 값을 반환하는 람다는 void lambda의 위치에서 합법적으로 사용될 수 있습니다. errorprone/FunctionalInterfaceClash

JLS 15.12.2.1 인용

본문 람다는 문 식 가 그 기능 유형의 기능적 인터페이스와 호환되는 것을 말한다 공극 복귀 또는 값이 반환 :

  • 람다 식 (§15.27)은 다음 내용이 모두 해당 될 경우 기능 인터페이스 유형 (§9.8)과 잠재적으로 호환됩니다.

  • 대상 유형의 함수 유형의 인수는 람다 식의 과 동일합니다. 대상 유형의 함수 유형이 void return을 갖는 경우 람다 본문은 문 표현

  • (14.8) 또는 void 호환 가능 블록 (15.27.2) 중 하나입니다. 대상 유형의 함수 유형이 (비공유) 리턴 유형을 갖는 경우, 람다 본문은 표현식 또는 값 호환 가능 블록 (§15.27.2) 인 입니다. 위의 구현 주어진 즉

, 잘 해결 것입니다 소비자와 기능 람다를 전달하지만 우리는 사실을 반환하는 람다를 사용하여 소비자를 구현하려는 사용 사례가있다 값.

Functions.named(name, Objects::requireNonNull); 
Functions.named(name, it -> Objects.requireNonNull(it)); 

은 우리가 다음과 같이 명시 적으로 문 블록을 추가 할 필요가 작동하려면 :

예를 들어이 두 실패

Functions.named(name, it -> { Objects.requireNonNull(it); }); 

을이 에지 경우이지만, 나는 문서 수 API에서 이것은 가독성의 절충점을 변경하므로 메서드의 이름을 다음과 같이 변경합니다.

Functions.fun(name, delegate) 
Functions.con(name, delegate) 
Functions.pre(name, delegate) 
Functions.sup(name, delegate) 
모든 것이 named 인 것만 큼 좋지는 않지만 여전히 읽기 쉽고 일관성이 있습니다.

간단히 말해서 코드 이름은 namedFunction이지만 코드베이스에서 사용되는 빈도를 감안할 때 좀 더 간결하게 표현할 수 있습니다.