2011-09-27 30 views
9

Tôi đã thử với một số sản phẩm khai thác khác nhau sau nó. Tôi có một số "dọn dẹp" mã mà chỉ nên chạy nếu có một ngoại lệ ném. Tôi có thể thêm cùng một mã vào mỗi ngoại lệ, nhưng điều đó trở thành một cơn ác mộng bảo trì. Về cơ bản, tôi muốn một cái gì đó giống như tuyên bố cuối cùng, nhưng cho nó để chỉ chạy nếu một ngoại lệ đã được ném.Làm thế nào để làm cho mã chạy chỉ khi một ngoại lệ đã được ném?

Điều này có khả thi không?

+0

Có phải các lỗi thời gian chạy mà bạn đang gặp phải hoặc lỗi kinh doanh của riêng bạn. – Shahzeb

+0

IOException, ClientProtocolException, UnsupportedEncodingException, vv – Bromide

Trả lời

18

Không có sự hỗ trợ trực tiếp nào cho điều này. Làm thế nào về một cái gì đó như thế này

boolean successful = false; 
try { 
    // do stuff 
    successful = true; 
} catch (...) { 
    ... 
} finally { 
    if (!successful) { 
     // cleanup 
    } 
} 
1

Điều duy nhất tôi có thể nghĩ là đặt biến trong mỗi lần bắt và sau đó kiểm tra biến đó cuối cùng.

Mã giả:

Boolean caught = false; 

try { 

    //risky code here 

catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
finally { 
    if (caught) { 
     // Do clean up 
    } 

} 
0

Tại sao bạn không chỉ cần sử dụng đơn giản thử & bắt?

try 
{ 
    foo(); 
} 
catch(Exception1 e1) 
{ 
    dealWithError(1); 
} 
catch(Exception2 e2) 
{ 
    dealWithError(2); 
} 
catch(Exception3 e3) 
{ 
    dealWithError(3); 
} 

... 

private void dealWithError(int i) 
{ 
    if(i == 1) // deal with Exception1 
    else if(i == 2) // deal with Exception2 
    else if(i == 3) // deal with Exception3 
} 
+2

chính xác những gì không có cơ thể nên làm. Cơn ác mộng trên đường 'if'. – Shahzeb

1

tôi có thể thêm mã tương tự để từng ngoại lệ, nhưng điều đó sẽ trở thành một cơn ác mộng bảo trì.

Hoặc nếu bạn xóa hết các 'ngoại lệ':

tôi có thể thêm mã cùng với nhau [nơi], nhưng điều đó sẽ trở thành một cơn ác mộng bảo trì.

Đây là phương pháp được tạo cho.

private void cleanup() { /* clean up */ } 

... 

try { 
    // oh noes 

} catch (MyException me) { 
    cleanup(); 
} catch (AnotherException ae) { 
    cleanup(); 
} 

Gặp rắc rối về bảo trì!

+2

Ngoại trừ việc bây giờ bạn không có quyền truy cập vào nội dung bên trong người gọi. Nếu đó là những gì cần làm sạch, bạn đang hosed. Và nếu bạn vượt qua những thứ lộn xộn, thì bạn đang mã hóa cứng danh sách các công cụ cần sửa - và nếu danh sách đó thay đổi sau này, bạn phải thay đổi mọi nơi sử dụng nó. Và bạn sẽ bỏ lỡ một. – cHao

+0

Ồ, và chức năng 'cleanup' này sẽ * chắc chắn * là' riêng tư ', nếu bạn khăng khăng đòi nó. – cHao

+0

@cHao Trong khi ture và cuối cùng là chắc chắn đẹp hơn, nếu bạn bỏ lỡ một nơi mã chỉ sẽ không biên dịch, vì vậy đó là ít xấu vẫn – Voo

0

Bạn có thể thử gói hai lớp xử lý ngoại lệ, và rethrow ngoại trừ sau khi bạn đã thực hiện việc xử lý chung:

try { 
     try { 
      // your code goes here 

     } catch (Throwable t) { 
      // do common exception handling for any exception 
      throw t; 
     }  

    } catch (NullPointerException nx) { 
     // handle NPE 
    } catch (Throwable t) { 
     // handle any other exception 
    } 

Không chắc tôi thực sự thích giải pháp này mặc dù ... cảm thấy như một chút của một hack. Tôi có thể thay vì nhìn thấy ngoại lệ xử lý một cách rõ ràng trong mỗi trường hợp, ngay cả khi điều này có nghĩa là lặp lại một cuộc gọi đến một số loại chức năng dọn dẹp được chia sẻ.

Các vấn đề liên quan