2012-03-23 5 views
1

저는 Java가 처음입니다. 파일을 읽고, SHA1 체크섬을 계산하고, 결과를 다른 파일에 쓰는 프로그램을 작성 중입니다. 어떤 오류든지 stderr에 메시지를 출력하고 지정된 종료 상태로 System.exit()을 호출하여 실행을 종료하는 함수 err_exit()을 호출하고 있습니다.Java : 예외 및 '초기화되지 않았을 수 있습니다.'

public static void main(String[] args) { 
    String in_fname = "C:/tmp/test.txt"; // not reading args yet 
    String out_fname = "C:/tmp/test.sign"; 
    byte[] file_data; 
    String hexdigest; 

    try { 
     file_data = readFileAsByteArray(in_fname); 
    } 
    catch (java.io.IOException ex) { 
     file_data = new byte[] {0}; // note this line well, please 
     err_exit(2, "error opening input file '" + in_fname + "'"); 
    } 

    try { 
     hexdigest = hexdigestSha1(file_data); 
    } 
    catch (NoSuchAlgorithmException ex) { 
     hexdigest = ""; // note this line well, please 
     err_exit(3, "could not compute SHA1 message digest!"); 
    } 

    try { 
     writeFileFromString(out_fname, hexdigest); 
    } 
    catch (java.io.IOException ex) { 
     err_exit(2, "error writing output file '" + out_fname + "'"); 
    } 

    System.exit(0); // success 
} 

내가 충분히주의하도록 요청 두 줄이 있습니다 : 이것은 내 main() 기능이 어떻게 생겼는지 약이다. 이 두 줄은 컴파일러가 변수가 초기화되지 않았다고 불평하지 않기 위해 존재합니다.

컴파일러가 알 수있는 한 catch 블록이 계속 될 수 있습니다. 사실 err_exit()은 절대로 돌아 오지 않으므로 잘못된 값이 전달 될 가능성이 없습니다.

그래서, 내 질문 :이 일을 처리하기위한 일반적인 Java 관용어는 무엇입니까? try/catch 블록의 행은보기 흉한 것입니다. 다양한 함수를 err_exit()이라고하고이 코드를 명시 적으로 사용하지 않도록 권하고 싶습니다. 나는 명시적인 체크를 선호한다고 생각하고, main() 함수가 체크를하기에 적합한 곳이지만, 나는 피드백에 관심이있다.

try/catch 블록을 사용하려는 경우 컴파일러 경고를 무시하는 좋은 방법입니까?

파이썬에서이 작업을 수행했다면 예외를 잡아 내지 못하고 프로그램이 스택 추적으로 멈추도록 할 수 있습니다. 오류가 발생하면 스택 추적은이 사용자가 나인 이래로이 프로그램의 사용자에게 큰 충격을주지는 않습니다. 내 main() 함수를 throws Exception으로 선언하면 예외를 잡을 수없고 파이썬처럼 동작합니다. 바로 생각하는 자바 사람들이 나를 피하려고하는 끔찍한 생각입니까?

P. 당신이 좋아하는 책/웹 페이지/내가 읽어야 할 Java 관용구가 있다면, 그것을 언급하십시오.

편집 : 변수 이름에 밑줄을 사용하여 사과드립니다. 나는 이미 실제 프로그램에있는 것들의 이름을 바꿨지만, 나는 그대로두고있다. 실제로 Python과 C로 프로그래밍하는 데 많은 시간을 소비했기 때문입니다. 나는 Python "PEP 8"스타일이나 일반적인 C 스타일을 사용하여 선택을했습니다.

+0

두 변수를 선언 한 행을 게시하십시오. –

+0

누락 된 자료를 추가하여 완전한 기능을 보였습니다. StackOverflow가 구문 색칠을 지금하고 있기 때문에 더 좋아 보입니다 ... 이전에는 없었습니다! – steveha

답변

2

강한 C 배경이있는 것 같습니다. 컴파일러가 file_data와 같은 변수에 대해 불평한다고 가정합니다. 단순히 try-catch 블록 위에 file_data = null을 추가하십시오. 위의

몇 가지 포인트 :

  1. 나는 하나의 블록에있는 모든 문을 결합하는 것이 안전하다고 생각합니다. 예외가 발생하면 프로그램은 올바른 예외 블록으로 즉시 분기합니다. 그것도 훨씬 못생긴 보일 것입니다.
  2. 일반적으로 다른 방법은 catch 블록 내에서 호출되지 않습니다. 작업은 (일반적으로 가능하면) 짧아야합니다. 오류를 처리하고 계속하거나 종료하십시오 (예외를 다시 throw 할 수 있음).
  3. System.exit()는 악합니다. 시스템을 종료하려면 (즉, 복구 할 수없는 오류 조건) 래핑 된 RuntimeException을 던지십시오. System.exit()로 인해 비 정리 상태가 발생할 수 있습니다.오히려 을 사용하여 새로운 RuntimeException (e);
  4. 마지막으로, 내가 둔감 해 보이는 경우 Java 규칙은 err_exit 대신 errExit로 메소드/변수 이름을 작성하는 것입니다. 나는 등 readFileAsByteArray, 호출의 결과에 행위하려는 시도에 실패한 접속 후 즉시 종료 될 것입니다 긍정적 인 경우에
+0

흠. 질문을 게시하기 전에 항상 StackOverflow를 검색하여 응답 여부를 확인합니다. "이 변수는 초기화되지 않았을 수 있습니다"라는 오류에 대한 수많은 논의가 있으며 그 중 몇 가지는 "필요할 때까지 변수를 초기화하지 말고 컴파일러에서 도움을주고 자 할 때/컴파일러가 당신을 도울 수있는 변수를 초기화하십시오. " 그 충고에 전반적으로 동의하지 않습니까? – steveha

+0

질문에 대한 편집 :-) 경고의 관점에서 보면 byte [] file_data = null; RuntimeException 당신을 위해 스택 추적을 표시합니다 ... 그래서 당신이 원하는 것 같아요. –

+0

컴파일러가 불평을 피하기 위해 초기화하는 것이 좋습니다. 대개 게으른 초기화는 완벽한 의미를 갖지만 실제 값 (즉, null이 아닌 값)이 알려진 경우에만 가능합니다. 나는 "변수 = null을 사용하고있다;" 나이를위한 지역 변수에 대해 ... 누군가가 나에게 나쁜 스타일이라고 말하면 나는 가장 놀랄 것이다. (나는 대안을 원할 것이다.) –

0

, 나는 아마 선언에 null 값을 할당하는 것 대지. 이 같은 ...

byte[] file_data = new byte[] {0}; 

... catch 블록의 "가짜"할당없이 나머지 코드가 이어집니다.

2

컴파일러는 throw가 반환되지 않는다는 것을 이해하고 err_exit()가 반환되지 않는다는 것을 이해하지 못합니다. 무시한 예외를 사용하여 다시 작성한다면 코드가 더 깨끗하고 컴파일러가 더 행복해집니다. Java 명명 규칙을 사용할 수도 있습니다.

public static void main(String[] args) { 
    String inFname = "C:/tmp/test.txt"; // not reading args yet 
    String outFname = "C:/tmp/test.sign"; 
    try { 
    processFile(inFname, outFname); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    throw e; // rethrow and let main() die 
    } 
}   

public static void processFile(String inFname, String outFname) 
    throws IOException, NoSuchAlgorithmException { 
    Byte[] fileData = readFileAsByteArray(inFname); 
    String hexDigest = hexdigestSha1(fileData); 
    writeFileFromString(outFname, hexDigest); 
} 

호출 루틴에서 오류를 잡을 수 있습니다. IOException이 발생할 수있는 다른 장소를 구별 할 필요가 있다면 루틴을 잡아서 설명적인 오류를 발생시킬 수 있습니다.

코드에 대한 최소한의 수정은 변수를 설정하는 try catch 블록 외부에서 null로 초기화하는 것입니다. 그렇다면 컴파일러는 행복 할 것입니다.

+0

총 Java 초보자를 기억하십시오. Jaco Van Niekerk의 답을 종합하여, "new_timeout (mesg)"에 "some_file_name 파일을 읽을 수 없습니다"와 같은 메시지를 지정했다고 생각합니다. – steveha

+0

두 가지 대답을 받아 들일 수 있다면이 질문을 받아 들일 수도 있습니다. 나는 그것을 upvote 않았다. 감사. – steveha

2

개인적으로 나는 "null을 던집니다"; 단순히 리턴 할 수없는 메소드를 호출 한 후.

관련 문제