2016-10-17 6 views
5

나는 람다 및 간단한 값을 varag에 통합하려고합니다.자바 vararg 패스 람다 및 값

public static void Log(String format, Object ... args) { 
    final Object[] fmt = new Object[ args.length ]; 
     for(int i = 0; i < args.length; i++) 
      fmt[i] = args[i] instanceof Supplier ? 
        ((Supplier) args[i]).get() : 
        args[i]; 
    final String s = String.format(format, fmt); 
    System.err.println(s); 
} 

final Supplier 
    s =() -> "aaa", 
    d =() -> 111; 
Log("%s %d %s %d", "bbb", 222, s, d); // OK, OUTPUT: bbb 222 aaa 111 
Log("%s %d %s %d", "bbb", 222,() -> "aaa",() -> 111); // COMPILE FAIL 

오류 : 메서드 로그는 주어진 유형에 적용 할 수 없습니다. REQUIERED String, Object [] found : String, String, int,() -> "aaa",() -> 111 이유 : 가변 인자 불일치; 객체가 함수 인터페이스가 아닙니다.

람다와 값을 모두 vararg에 전달할 수 있습니까?

+0

varargs는 같은 유형이어야합니다. 'Log ("% s % d % s % d", (Object) "bbb", (Object) 222, (Object)() -> "aaa" , (Object)() -> 111); –

+1

@ Timothy Truckle 해당 솔루션은 여전히 ​​컴파일러 오류를 제공합니다. – n247s

+0

(Object)를 시도했지만 도움이되지 않습니다. (공급 업체) 캐스팅이 문제를 해결했습니다. – Dmitry

답변

4

문제는 당신은 객체가 인터페이스없는 (정확히 하나 개의 추상 메소드 하나) 기능 인터페이스에 대한 람다를 만들 수 있습니다

Object is not a functional interface

오류 메시지에이며 어떤 추상적 인 방법이 없습니다 따라서이 유형의 람다를 만들 수는 없습니다. 당신이 할 수있는 컴파일러는 구현하도록 람다 어떤 종류의 알고이 방법

Log("%s %d %s %d", "bbb", 222, (Supplier)() -> "aaa", (Supplier)() -> 111); 

입니다.

비교해 보면 다음과 같이 작성할 수 있으며 이는 사용자의 방식에 따라 다르게 작동합니다.

Log("%s %d %s %d", "bbb", 222, (Callable)() -> "aaa", (Callable)() -> 111); 
0

문제는 Object@FunctionalInterface되지 않는 것입니다. 즉, 다음과 같은 간단한 익명의 인스턴스를 전달할 수 있습니다 말했다되는 : 당신은 컴파일러 경고가 발생합니다 체크되지 않은 캐스트를 사용하지 않으려면

Log("%s %d %s %d", "bbb", 222, new Supplier<String>() { 
      @Override 
      public String get() { 
       return "aaa"; 
      } 
     }); 

이 방법을 사용할 수 있습니다.

당신은 여전히 ​​수행 할 수 있습니다 이런 식으로 당신의 람다 캐스팅 할 경우 컴파일러를 들어

Log("%s %d %s %d", "bbb", 222, (Supplier<String>)() -> "aaa"); 
+1

내 대답은 귀하의 대안입니다. –

+0

@Whomever downvoted : 설명해 주시겠습니까? –

+0

그게 무슨 문제입니까? Lambdas는'@ FunctionalInterface' 주석이 붙은 익명의 내부 클래스에 대한 문법적 설탕입니다. –

0

첫 번째는 달리 (을 delcare 때 사용되는 기능 인터페이스의 종류를 알 수있는 방법이 없기를 하나, 변수 유형에서 정의한 이후)

따라서 수정 프로그램이 공급 업체를 캐스팅합니다. 예 : (테스트되지 않음)

Log("%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111)); 

올바른 방향으로 가리 키길 바랍니다.