2010-04-12 2 views
1

if-clause에서 예외 처리가 매우 오류가 발생했습니다. 경로를 찾을 수없는 경우 예외가 발생합니다. 예외는 함수를 다시 리턴합니다. 이 함수는 재귀 적입니다. 안전한?Java : IOException에 의한 위험한 자체 반환 - 재귀 함수?

 
$ javac SubDirs.java 
$ java SubDirs 
Give me an path. 
. 
Dir1 
Dir2 
Give me an path. 
IT WON'T FIND ME, SO IT RETURNS ITSELF due to Exception caught 
Give me an path. 

Subdirs.java의 코드는 다음과 같습니다 : 당신이 잘못된 경로를 수천 번을 입력 할 때까지

import java.io.*; 
import java.util.*; 

public class SubDirs { 
    private List<File> getSubdirs(File file) throws IOException { 
     List<File> subdirs = Arrays.asList(file.listFiles(new FileFilter() { 
        public boolean accept(File f) { 
        return f.isDirectory(); 
        } 
        })); 
     subdirs = new ArrayList<File>(subdirs); 

     List<File> deepSubdirs = new ArrayList<File>(); 
     for(File subdir : subdirs) { 
      deepSubdirs.addAll(getSubdirs(subdir)); 
     } 
     subdirs.addAll(deepSubdirs); 
     return subdirs; 
    } 

    public static void search() { 
     try{ 
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
      String s; 
      System.out.println("Give me an path."); 
      while ((s = in.readLine()) != null && s.length() != 0){ 
       SubDirs dirs = new SubDirs(); 
       List<File> subDirs = dirs.getSubdirs(new File(s)); 
       for (File f : subDirs) { 
        System.out.println(f.getName()); 
       } 
       System.out.println("Give me an path."); 
      } 
     }catch(Exception e){ 
        // Simple but is it safe? 
      search(); 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     search(); 
    } 
} 
+2

질문을 수정 해 주실 수 있습니까? 네가 무엇을 요구하는지 이해하는 데 어려움이있다. –

+0

@Sauer : A를 재귀 함수라고합시다. def로 B는 A를 반환하기 때문에 재귀 적입니다. try-catch-loop를 사용하여 내부 재귀 함수로 재귀 함수를 갖는 것이 안전합니까? – hhh

+0

B 자신을 반환합니다. A 자체를 반환합니다. B는 A를 내부 구조로 갖는다. A는 getSubDirs이고 B는 검색입니다. – hhh

답변

1

토론 할 수 있습니다. 나는 이것이 쓸모없는 스택 프레임을 엉망으로 만든다고 생각할 것이다. 모바일 장치에서이 코드를 재사용하지 않는다면 걱정할 필요가 없을 것이다. 그럼에도 불구하고 더 좋은 방법이 없다는 것을 더 이상 확신하지 않으면 코드 검토를 통과시키지 않을 것입니다.

더 나은 이해도 및 유지 보수를 들어,을 의미하는 것을 코딩 의 습관을 : 당신이 오류에 재 시도 루프에 코드를하려는 경우, 다음 루프를 코딩. 재귀는 더 매끄럽지 만, 예외 처리기에서 일반적인 관행이 아니기 때문에 깜짝 요소가 증가합니다. 내가이 코드를 앞으로 유지 보수한다면, 재귀가 의도적인지 또는 버그인지 궁금 할 것입니다. 재귀를 의도적으로 설명하는 설명을 남겨주세요.

더 나은 유지 보수와 나중에 문제 해결을 쉽게하기 위해 평범한 코드를 몇 줄 더 추가하여 기꺼이 교환 해 드리겠습니다.

public static void search() { 

    boolean succeeded = false; 
    int attemptsLeft = MAX_ATTEMPTS; 
    while (! succeeded && (--attemptsLeft > 0)) { 

    try{ 
     BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
     String s; 
     System.out.println("Give me an path."); 
     while ((s = in.readLine()) != null && s.length() != 0){ 
      SubDirs dirs = new SubDirs(); 
      List<File> subDirs = dirs.getSubdirs(new File(s)); 
      for (File f : subDirs) { 
       System.out.println(f.getName()); 
      } 
      System.out.println("Give me an path."); 
     } 

     succeeded = true; 

    }catch(Exception e){ 
     // ALWAYS LEAVE YOURSELF A CLUE TO WHAT HAPPENED 
     // e.g. the exception caught may not be the exception you expected 
     e.printStackTrace(); 
    } 

    } // while not succeeded yet 

    if (! succeeded) { 
    log("Hmm ... bailing search() without succeeding"); 
    } 
} 
2

예, 그것은 안전합니다.

0

search()가 실패 할 때마다 호출 스택에 search()의 또 다른 인스턴스를 만듭니다. 이 경우 사용자에게 입력을 요구하는 것처럼 스택이 오버플로되기 훨씬 전에 사용자가 포기할 가능성이 높기 때문에 위험은 미미합니다. 그러나 실패한 경우 다시 시도하거나 잠재적으로 긴 목록의 다음 항목으로 이동 한 앱이있는 경우이 방법으로 스택을 오버플로 할 수 있습니다.

더 나은 방법은 while 루프 안에 try/catch 블록을 넣고 재귀 호출 대신 실패 할 때 루프를 다시 통과하는 것이 좋습니다. 다음과 같은 것 - 경고 - 테스트되지 않은 제안 코드 :

public static void search() { 
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
    String s; 
    System.out.println("Give me an path."); 
    while ((s = in.readLine()) != null && s.length() != 0){ 
     try 
     { 
      SubDirs dirs = new SubDirs(); 
      List<File> subDirs = dirs.getSubdirs(new File(s)); 
      for (File f : subDirs) { 
       System.out.println(f.getName()); 
      } 
     } 
     catch (Exception e) { 
      System.out.println("Something went wrong! Everybody scream and run in circles!"); 
     } 
    System.out.println("Give me an path."); 
    } 
}