2012-01-06 23 views
6

Tôi có một khối try - catch mà tôi muốn break như một khối switch nhưng tôi không thể tìm thấy cách được khuyến nghị để thực hiện. Tôi đang tìm nạp nhiều dữ liệu trong khối try - catch và muốn dừng tìm nạp ở giữa trong trường hợp một điều kiện nhất định được đáp ứng. Chỉ cần để làm cho nó làm việc cho bây giờ, tôi đã cố tình buộc mã đi vào khối catch:Cách tốt nhất để buộc một khối thử phá vỡ ở giữa là gì?

int i=0; 
    try { 
     //--do stuff---- 
     if(//-------is condition met?--------//) 
      i = 1/0; // divide 1 by 0 -- a definite exception 
    } 
    catch (Exception e) {//---------do nothing---------//} 

có an toàn để làm điều này hay tôi nên đi cho một cách khác?

EDIT: Tôi đang tìm nạp một số dữ liệu xml (thực sự, rất nhiều). Tùy thuộc vào kết nối internet, tôi cần dừng phân tích sau một thời gian (hết thời gian) thay vì đi qua toàn bộ luồng. Tôi đi qua các vòng nhưng tôi cũng thực hiện một số tính toán sau. Nó không có ý nghĩa để tính toán với dữ liệu không đầy đủ, vì vậy tôi muốn chỉ bỏ qua toàn bộ điều.

+5

Đó là một cách khủng khiếp: bạn có thể đăng một ngữ cảnh đầy đủ hơn không? Một cách ít xấu hơn là sử dụng một vòng lặp "giả" và phá vỡ đó, đó là một thành ngữ C ngu ngốc, nhưng tôi nghi ngờ có thể có một cách tốt hơn để cấu trúc mã hoàn toàn. –

+4

Thật kinh khủng. – SLaks

+0

Tôi đồng ý với @pst; mà không nhìn thấy một ví dụ lớn hơn (cụ thể là, bạn đang cố gắng bỏ qua điều gì?), thật khó để trả lời câu hỏi này một cách có ý nghĩa. –

Trả lời

3

Hoặc break hoặc throw sẽ làm những gì bạn muốn (và throw sẽ là thích hợp hơn, bạn ít nhất có một số truy xuất nguồn gốc để WTH ​​bạn đang làm.

[sửa]

what: try { 
     System.out.println ("before break"); 
     break what; 

     } catch (Exception e) {} 
    } 

[/chỉnh sửa]

+1

Bạn cũng có thể sử dụng một goto. – Max

+4

'goto' là gì? – KevinDTimm

+0

@Max [Không phải trong java] (http://stackoverflow.com/questions/2545103/is-there-a-goto-statement-in-java) –

0

Chỉ cần đặt phần còn lại của việc tìm nạp vào một khối nếu có điều kiện nghịch đảo:

//--do stuff---- 
if (!shouldStop) { 
    // continue doing stuff 
} 
0

Nhìn bởi mã của bạn

int i=0; 
    try { 
     //--do stuff---- 
     if(//-------is condition met?--------//) 
      i = 1/0; // divide 1 by 0 -- a definite exception 
    } 
    catch (Exception e) {//---------do nothing---------//} 

nếu tình trạng này không được đáp ứng? sau đó bạn không cần phải lo lắng về việc sử dụng giờ nghỉ,

nếu điều kiện được đáp ứng, sẽ có chắc chắn là một ngoại lệ, và nó được xử lý trong catch (mặc dù bạn không làm bất cứ điều gì)

9

Mã này mùi một số chống mẫu nhưng không có nhiều bối cảnh, chúng tôi không thể quy định một thiết kế tốt hơn. Nói chung, bạn chỉ nên ném ngoại lệ cho một điều kiện đặc biệt đặc biệt ở trạng thái chương trình của bạn. Bạn nên đặc biệt là không ném ngoại lệ cho luồng điều khiển bình thường (dự kiến), thay vào đó bạn nên sử dụng các câu lệnh điều khiển luồng như vòng lặp (sử dụng break/continue) và return.

Nếu bạn muốn giữ lại cấu trúc này (mặc dù bạn không nên) sau đó tôi khuyên bạn nên ném một cách rõ ràng một lớp ngoại lệ đặc biệt để làm cho nó rõ ràng những gì bạn đang làm, ví dụ:

public static class ConditionMetException extends Exception { } 

// ... 
try { 
    // do stuff 
    if (/* Is condition met? */) { 
    throw new ConditionMetException(); 
    } 
} catch (ConditionMetException cme) { /* Do nothing. */ } 

Nhưng một lần nữa, bạn có khả năng tốt hơn để tái cấu trúc để sử dụng một vòng lặp và được xây dựng trong lệnh break.

+0

Tên mỉa mai của ngoại lệ là đủ để cho biết rằng đây thực sự là một ý tưởng tồi để thực hiện. Tôi không có nghĩa rằng như một lời chỉ trích của câu trả lời (mà trả lời những gì đã được yêu cầu một cách sạch sẽ bằng cách làm cho một ngoại lệ cụ thể cho nó), nhưng ý tưởng nói chung. Điều này nên khá nhiều không bao giờ được khuyến khích. –

+0

-1 Có lẽ hôm nay tôi đang trong tâm trạng lo lắng, nhưng tôi không thể tin rằng một gợi ý để ném "ConditionMetException" cho một thứ không đặc biệt và đang được sử dụng để kiểm soát luồng chương trình bình thường có 5 upvotes. – user949300

+0

@ user949300: đã đồng ý, đó là lời khuyên khủng khiếp nhưng vẫn tốt hơn một chút so với mẫu của riêng anh ấy. Bạn có đề nghị gì? – maerics

0

Nếu không có cách nào khác mà bạn có thể sử dụng một nhãn khối

load:{ 
     if(test)//skip the remaining load block 
     break load; 

    } 

Nếu không, bạn có thể cấu trúc lại mã nạp vào một phương pháp khác nhau và trở về sớm.

1

Ném ngoại lệ chỉ để phá vỡ là thực hành không tốt.

Điều này có phù hợp với hoàn cảnh của bạn không?

  1. Đặt mã hiện đang được thử vào phương thức khác, fetchLotsOfData(). Nó vẫn có thể ném IOException hoặc bất cứ điều gì là thích hợp.
  2. Khi bạn muốn ngừng làm việc tìm nạp dữ liệu, chỉ cần quay lại. Có lẽ trả lại một số đúng/sai hoặc trạng thái cho sự thành công.

Vì vậy, mã cuối cùng của bạn là một cái gì đó giống như

int recordsRead = -1; // -1 means failure 
try { 
    recordsRead = fetchLotsOfData(); 
} 
catch (IOException ioe) { 
    // handle the exception 
} 

// process what you got... 
1

Nó không phải là try-catch mà bạn nên lo lắng về việc phá vỡ ra khỏi. Từ những gì tôi có thể nói, bạn đang tìm kiếm để làm điều gì đó dọc theo các dòng:

try 
{ 
    // do thing 1 

    // do thing 2 

    if (!done) 
    { 
    // do thing 3 

    // do thing 4 

    if (still not done) 
    { 
     // do thing 5 
    } 
    } 
} catch (Exception e) 
{ 

} 

Nếu đó là những gì bạn đang cố gắng làm, thì đó có lẽ là cách bạn nên làm điều đó (thay vì cố gắng trốn thoát try-catch). Cách khác là thu nhỏ các khối try-catch của bạn để bao quanh từng tác vụ riêng lẻ.

Nếu bạn cung cấp thêm ngữ cảnh cho câu hỏi của mình thì có thể cung cấp câu trả lời tốt hơn.

1

Tôi sẽ trả lời "là một ý tưởng hay?" một phần của câu hỏi: Số

Không nên sử dụng ngoại lệ để thực hiện kiểm soát luồng dự kiến. Nó có thể, nhưng không được mong đợi, cũng giống như nó có thể làm cho tất cả các biến của bạn Strings và thực hiện tất cả các cấu trúc dữ liệu của bạn trong mảng.

Các khối thử dùng để tạo ranh giới phạm vi có bảo đảm nhất định khi chấm dứt (hành vi catchfinally). Người bảo trì mã đang xem:

try{ ... }catch(Exception x){} 

sẽ rất mạnh hoặc có thể trả lại x (có thể được bao bọc) hoặc loại bỏ hoàn toàn khối.

Các khối thử không phải là về là gì bên trong phạm vi của chúng. Đó là cấu trúc vòng lặp tiêu chuẩn và các hàm tốt hơn. Câu hỏi của bạn chỉ đơn giản biến mất nếu bạn đặt phạm vi của mình vào một hàm:

RetVal doStuff(Arg arg){ 
    //--do stuff---- 
    if(//-------is condition met?--------//) 
     return myResult; 
} 
0

Không sử dụng ngoại lệ để xử lý lỗi không ngoại lệ. Đây có thể là một mẫu chống tên. Nếu vậy, tôi không biết tên.

Dưới đây là một ví dụ về vi phạm ra khỏi một vòng lặp khi một ngoại lệ được ném và không sử dụng xử lý ngoại lệ để thực hiện xử lý lỗi không ngoại lệ:

try 
{ 
    while (... whatever ...) 
    { 
    ... do something that might throw a BlammoException. 
    } 
} 
catch (BlammoException exception) 
{ 
    ... handle the exception. 
} 
0

Chỉ cần ném bất cứ ngoại lệ nào bạn muốn bắt ...

boolean stopLoop = false; 
while (!stopLoop) { 
    try { 
     int key = Integer.parseInt(userInput); 
     if (key > cutOff) throw new NumberFormatException();//<--like this 
     else { 
      System.out.println("Good job, your number didn't suck"); 
      //do some stuff... 
      stopLoop = true;//<--End loop after some stuff 
      //some more stuff, or.. 
      if(nomorestuff)break;//<--exit loop 
     } 
    catch (NumberFormatException nfe){ 
     System.err.println("Enter a number less than "+cutOff); 
    } 
}//end while 
Các vấn đề liên quan