2016-11-03 4 views
4

람다 식에 문제가 있습니다. 내 코드 :람다 식 처리 예외

public static void main(String[] args) throws IOException { 

    Function<String, String> lambda = path -> { 
     String result = null; 
     BufferedReader br = new BufferedReader(new FileReader(path)); 
     String line; 
     while ((line = br.readLine()) != null) { 
      result = result + line; 
     } 
     return result; 
    }; 
} 

그건 가능 :

public static void main(String[] args) { 

    Function<String, String> lambda = path -> { 
     String result = null; 
     try { 
      BufferedReader br = new BufferedReader(new FileReader(path)); 
      String line; 
      while ((line = br.readLine()) != null) { 
       result = result + line; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return result; 
    }; 
} 

은 그 같은 코드를 만들기 위해 지금 노력하고있어? java.util.function 만 사용할 수 있습니다. "lambda"에서 try catch를 삭제하려고하고 내 "main"메소드가 해당 Exception을 catch해야합니다.

+0

참고 첫 번째 솔루션으로 메모리 누수를 일으키는 원인이되는'BufferedRead'을 닫습니다 결코. – Spotted

답변

4

apply() method의 서명에서 볼 수 있듯이 내장 된 Function 클래스는 검사되지 않은 예외를 throw하지 못하게합니다.

당신은 그러나 쉽게 정의 할 수 있습니다 자신의 허가 예외가 throw 않습니다 @FunctionalInterface, 예컨대 :

@FunctionalInterface 
public interface CheckedFunction<U,V> { 
    public V apply(U u) throws Exception; 
} 

그리고 당신의 lambda 변수 대신 CheckedFunction합니다.

Function<Foo,Bar> f = foo -> { 
    try { 
    return foo.methodThatCanThrow(); 
    } catch (RuntimeException e) { 
    throw e; 
    } catch (Exception e) { 
    throw new RuntimeException(e); 
    } 
}; 

이가 코드를 허용합니다 :


대안, 당신 사용해야하는 경우는 내장 어떤 이유로 Function, 모든 RuntimeException의 예에 확인 된 예외를 설정하는 것입니다 컴파일하지만 일반적으로 권장되는 최선의 방법은 아닙니다.

+0

"java.util.function' 만 사용할 수 있습니다." –

+0

@MarkoTopolnik 왜? 어떤 종류의 의미없는 제한이 무엇입니까? java.util.function.Function'에서 예외를 throw 할 수는 없으며, lambda는 자신의 기능적 인터페이스를 정의 할 수 있도록 설계되었습니다. 람다를 예제 코드에서 사용하는 방식으로 사용하려면 다른 인터페이스를 사용해야합니다. – dimo414

+0

나를 OP와 혼동스럽게 생각합니다. –

2

dimo414 말했듯이, 먼저 새 functional interface

@FunctionalInterface 
public interface CheckedFunction<U, V> { 
    public V apply(U u) throws IOException; 
} 

가 그럼 난 다음에 람다 식을 리팩토링으로 한 단계 더 갈 것 선언

CheckedFunction<String, String> lambda = path -> { 
      try (BufferedReader br = new BufferedReader(new FileReader(path))) { 
       return br.lines().collect(Collectors.joining()); 
      } 
     }; 

try-with-resources는 폐쇄을 담당 모든 경우에 BufferedRead을 입력하고 stream API의 간결성을 사용하여 모든 행을 연결합니다.

Files을 사용하는 경우 두 번째 단계를 더 진행하면 더 이상 BufferedReader으로 신경 쓸 필요가 없습니다. 이것은 다음과 같은 람다까지 촬영 할 수 있습니다

CheckedFunction<String, String> lambda = path -> Files.lines(Paths.get(path)).collect(Collectors.joining());