2010-07-04 40 views
5

Tôi đang gặp một chút rắc rối khi triển khai phương pháp sau trong khi xử lý 3 ngoại lệ mà tôi phải lo. Tôi có nên bao gồm các khối thử/nắm bắt như tôi đang làm hay là để lại cho ứng dụng thay vì thiết kế lớp?Phương thức xử lý ngoại lệ Java

Phương pháp này nói rằng tôi là nghĩa vụ phải thực hiện điều này:

public Catalog loadCatalog(String filename) 
     throws FileNotFoundException, IOException, DataFormatException 

Phương pháp này sẽ tải thông tin từ các kho lưu trữ theo quy định tại một cửa hàng của các sản phẩm và trả về danh mục.

Bắt đầu bằng cách mở tệp để đọc. Sau đó, nó tiến hành đọc và xử lý từng dòng của tệp.

Phương pháp String.startsWith được sử dụng để xác định kiểu dòng:

  • Nếu loại đường là "sản phẩm", phương pháp readProduct được gọi.
  • Nếu loại dòng là "Cà phê", phương thức readCoffee được gọi.
  • Nếu loại dòng là "Brewer", phương thức readCoffeeBrewer được gọi.

Sau khi dòng được xử lý, loadCatalog thêm sản phẩm (sản phẩm, cà phê hoặc bia) vào danh mục sản phẩm.

Khi tất cả các dòng của tệp đã được xử lý, loadCatalog trả về Danh mục sản phẩm theo phương thức thực hiện cuộc gọi.

Phương pháp này có thể ném ngoại lệ sau:

  • FileNotFoundException - nếu các tập tin được chỉ định không tồn tại.
  • IOException - Nếu có lỗi khi đọc thông tin của tệp được chỉ định.
  • DataFormatException - nếu một dòng có lỗi (ngoại trừ phải bao gồm các dòng có dữ liệu sai)

Dưới đây là những gì tôi có cho đến nay:

public Catalog loadCatalog(String filename) 
     throws FileNotFoundException, IOException, DataFormatException{ 
    String line = ""; 
    try { 
     BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat")); 
      try { 
       BufferedReader input = new BufferedReader(
        new FileReader(stdIn.readLine())); 
       while(! stdIn.ready()){ 
        line = input.readLine();       
        if(line.startsWith("Product")){ 
         try { 
          readProduct(line); 
         } catch(DataFormatException d){ 
          d.getMessage(); 
         } 
        } else if(line.startsWith("Coffee")){ 
         try { 
          readCoffee(line);        
         } catch(DataFormatException d){ 
          d.getMessage(); 
         } 
        } else if(line.startsWith("Brewer")){ 
         try { 
          readCoffeeBrewer(line); 
         } catch(DataFormatException d){ 
          d.getMessage(); 
         } 
        } 
       } 
      } catch (IOException io){ 
       io.getMessage(); 
      } 
    }catch (FileNotFoundException f) { 
     System.out.println(f.getMessage()); 
    } 
    return null; 
} 

Trả lời

1

Ý tưởng chung là bạn lọc các ngoại lệ lên đến vị trí thích hợp để xử lý chúng. Tôi sẽ đoán rằng người hướng dẫn của bạn hy vọng họ sẽ được xử lý trong chính. Trong trường hợp này tôi có thể đoán rằng vì điều khoản ném bạn đã được đưa ra. Một quy tắc đơn giản là nếu phương thức khai báo ngoại lệ trong mệnh đề ném bạn không nắm bắt nó trong phương thức đó. Vì vậy, phương pháp bạn đang viết nên không có câu lệnh bắt.

Để làm điều đó bạn sẽ thay đổi điều gì đó mã của bạn như:

public Catalog loadCatalog(String filename) 
    throws FileNotFoundException, 
      IOException, 
      DataFormatException 
{ 
    String line = ""; 

    BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat")); 
    BufferedReader input = new BufferedReader(new FileReader(stdIn.readLine())); 

    while(!stdIn.ready()) 
    { 
     line = input.readLine(); 

     if(line.startsWith("Product")) 
     { 
      readProduct(line); 
     } 
     else if(line.startsWith("Coffee")) 
     { 
      readCoffee(line); 
     } 
     else if(line.startsWith("Brewer")) 
     { 
      readCoffeeBrewer(line); 
     } 
    } 

    return null; 
} 

và sau đó trong phương pháp (có lẽ chính) mà các cuộc gọi loadCatalog bạn sẽ phải:

try 
{ 
    loadCatalog(...); 
} 
catch(FileNotFoundException ex) 
{ 
    ex.printStackTrace(); 
} 
catch(IOException ex) 
{ 
    ex.printStackTrace(); 
} 
catch(DataFormatException ex) 
{ 
    ex.printStackTrace(); 
} 

thay thế printStackTrace với một cái gì đó thích hợp.

Bằng cách đó, phương thức loadCatalog không xử lý các thông báo lỗi, vì vậy bạn có thể gọi phương thức trong GUI hoặc mã giao diện điều khiển và mã gọi nó có thể chọn cách hiển thị lỗi cho người dùng (hoặc đối phó với nó theo một cách nào đó).

4

Nó phụ thuộc vào việc bạn muốn lớp hoặc một phần khác của ứng dụng đang sử dụng nó để xử lý ngoại lệ và làm bất cứ điều gì là bắt buộc.

Kể từ khi mã mà sẽ sử dụng loadCatalog()lẽ sẽ không biết phải làm gì với một tập tin I/O hoặc định dạng ngoại lệ, cá nhân, tôi muốn đi với việc tạo ra một ngoại lệ như CatalogLoadException và ném nó từ bên trong phương thức loadCatalog() và đặt nguyên nhân ngoại lệ (FileNotFoundException, IOException, DataFormatException) bên trong nó trong khi bao gồm thông báo cung cấp thông tin tùy thuộc vào trường hợp ngoại lệ nào được kích hoạt.

try { 
     ... 
    //do this for exceptions you are interested in. 
    } catch(Exception e) { 
     //maybe do some clean-up here. 
     throw new CatalogLoadException(e); // e is the cause. 
    } 

Bằng cách này phương pháp loadCatalog() của bạn sẽ chỉ ném một single và có ý nghĩa ngoại lệ.

Bây giờ mã sẽ sử dụng loadCatalog() sẽ chỉ phải xử lý một ngoại lệ: CatalogLoadException.

loadCatalog(String filename) throws CatalogLoadException 

này cũng cho phép phương pháp của bạn để ẩn chi tiết thực hiện vì vậy bạn không cần phải thay đổi nó "ngoại lệ ném" chữ ký khi mức thấp thay đổi cấu trúc cơ bản. Lưu ý rằng nếu bạn thay đổi chữ ký này, mọi đoạn mã sẽ cần thay đổi tương ứng để xử lý các loại ngoại lệ mới mà bạn đã giới thiệu.

Xem thêm câu hỏi này trên Exception Translation.


Cập nhật theo yêu cầu chữ ký ném:

Nếu bạn để giữ chữ ký mà sau đó bạn không thực sự có một lựa chọn nào khác throw họ ứng dụng và không catch họ bên trong phương pháp loadCatalog(), nếu không, chữ ký throws sẽ là vô dụng, vì chúng tôi sẽ không ném cùng một ngoại lệ chính xác mà chúng tôi vừa xử lý.

+0

cảm ơn cho mảnh lớn của tư vấn, họ sẽ thốt lên một kỹ thuật thiết kế tốt hơn để ném chỉ có 1 ngoại lệ để xử lý tất cả trong số họ. Ill cho nó một shot từ bây giờ. Tuy nhiên, tôi quên đề cập đến bài tập đặc biệt này (đối với trường học) tôi phải thực hiện phương pháp chính xác như được mô tả bởi vì sau đó tôi phải làm cho nó chạy thông qua một ứng dụng Tesfile được tạo trước và đảm bảo nó biên dịch. – edu222