10

tôi phải phân tích một chuỗi mà có thể giả định giá trị hex hoặc các giá trị phi hex khácCó đang đánh bắt NumberFormatException là một thực tế không tốt?

0xff, 0x31 hoặc A, PC, label, và vân vân.

tôi sử dụng mã này để phân chia hai trường hợp:

String input = readInput(); 

try { 
    int hex = Integer.decode(input);    
    // use hex ... 

} catch (NumberFormatException e) { 
    // input is not a hex, continue parsing 
} 

mã này có thể được coi là "xấu xí" hoặc khó đọc? Có giải pháp nào khác (có thể thanh lịch hơn) không?

EDIT: Tôi muốn làm rõ rằng (trong trường hợp của tôi) nhập sai không tồn tại: tôi chỉ cần phân biệt nếu đó là số hex hay không. Và chỉ để hoàn thành, tôi đang thực hiện một assebler đơn giản cho DCPU-16.

+0

Đây không nhất thiết phải là thực hành không tốt, nhưng nó có thể giúp hiển thị cho chúng tôi thông tin đầu vào trông như thế nào. IMO, bạn có thể ** không bao giờ ** làm đủ kiểm tra lỗi. –

+0

Tôi nghĩ rằng nó xấu xí và khó đọc, nhưng không có giải pháp nào tốt hơn. Đó là một trong những lý do tôi không thích ngoại lệ đã kiểm tra http://c2.com/cgi/wiki?TheProblemWithCheckedExceptions –

+1

Bạn có thể tìm thấy [câu hỏi này] (http://stackoverflow.com/q/5378005/387852) có liên quan . –

Trả lời

7

Xử lý ngoại lệ là một phần không thể thiếu (và một trong các mục tiêu thiết kế) của ngôn ngữ lập trình Java ... bạn không nên bỏ chúng ra chỉ vì bạn nghĩ chúng "xấu xí".

Điều đó nói rằng, nếu bạn muốn một cách đơn giản và dễ đọc để xử lý NumberFormatException s, bạn có thể cân nhắc sử dụng lớp NumberUtils để thay thế.

Phương thức toInt(String str, int defaultValue) chuyển đổi String thành int, trả lại giá trị mặc định nếu chuyển đổi không thành công. Nếu chuỗi là null, giá trị mặc định được trả về.

NumberUtils.toInt(null, 1) = 1 
NumberUtils.toInt("", 1) = 1 
NumberUtils.toInt("1", 0) = 1 

Phương pháp đóng gói ngoại lệ đánh bắt và xử lý, như đã thấy trong source code dưới đây. Kết quả là, khách hàng chỉ cần thực hiện một cuộc gọi phương thức duy nhất.

public static int toInt(String str, int defaultValue) {   
    if(str == null) { 
     return defaultValue; 
    } 
    try { 
     return Integer.parseInt(str); 
    } catch (NumberFormatException nfe) { 
     return defaultValue; 
    } 
} 
+0

tôi không nghĩ rằng điều này có thể giúp tôi, vui lòng xem câu hỏi đã chỉnh sửa. –

+0

@integeruser, nếu một đầu vào sai không tồn tại, thì tất nhiên mã của bạn là ok như đã viết ở trên ... trên thực tế, tôi không tin rằng có bất kỳ cách nào khác có thể bạn có thể tránh một vụ tai nạn chương trình mà không cần xử lý ' NumberFormatException' ... bạn có thể làm rõ vấn đề là gì không? –

+0

tôi phải kiểm tra xem chuỗi có phải là số hex hay không. Có mã của tôi hoạt động, nhưng tôi thấy nó xấu xí và tôi không nghĩ đó là cách tiếp cận tốt nhất. Xem câu trả lời của pb2q. –

0

Nó phụ thuộc vào ngữ cảnh, trong nhiều trường hợp nó xấu nhưng nếu nó sẽ là một nơi rất có khả năng có đầu vào xấu và bạn có một mặc định để đặt nó vào thì bạn sẽ muốn bắt nó.

2

Bạn là câu hỏi thứ hai tôi đã thấy hôm nay hỏi về điều này.

Không, nó hoàn toàn phù hợp để bắt ngoại lệ này.

Và nó chắc chắn hình thức tốt hơn để bắt một rõ ràng hơn ngoại lệ (như "NumberFormatException") hơn là một "ngoại lệ" chung chung.

IMHO ...

PS: đâu bạn đặt ngoại lệ: ở cấp độ này, hoặc cao hơn-up, là một câu hỏi khác nhau.

Quy tắc chung là "cấp thấp nhất nơi bạn biết điều gì đã xảy ra và cách tốt nhất để khôi phục".

Hoặc, để đặt nó một cách khác (trích dẫn từ một liên kết dưới đây):

"Một phương pháp duy nhất nên bắt một ngoại lệ khi nó có thể xử lý nó theo một cách hợp lý"

Dưới đây là một số thảo luận:

+0

Tôi không đồng ý rằng nó 'chắc chắn' tốt hơn để bắt ngoại lệ rõ ràng hơn. Nếu một số phương pháp có thể ném một số ngoại lệ và bạn không thể khôi phục đầy đủ từ bất kỳ trường hợp nào, thì tại sao lại bận tâm với bất kỳ điều gì khác ngoài việc bắt 'Ngoại lệ' (hoặc bất kỳ điều gì) và ghi nhật ký. Tôi đồng ý với mục được trích dẫn thứ hai, "một phương pháp chỉ nên bắt ngoại lệ ..." –

+0

Tôi không nghĩ câu trả lời của bạn thực sự giải quyết câu hỏi, mà ** không phải là về _how/khi nào tôi nên sử dụng ngoại lệ, nhưng về việc sử dụng Ngoại lệ khi nó có thể thích hợp hơn để sử dụng ví dụ nếu khác. – pb2q

1

Không, nó không phải là "thực hành xấu". Nó chỉ phụ thuộc vào tình hình. Ví dụ, với tư cách là một Android, nếu người dùng nhập chuỗi "123a" vào hộp văn bản chỉ được chấp nhận số nguyên và sau đó được phân tích cú pháp, một ngoại lệ sẽ được ném khiến ứng dụng gặp sự cố. Trong trường hợp này, nó sẽ có ý nghĩa hoàn hảo để bắt ngoại lệ và nhắc người dùng nhập lại văn bản.

+0

Nhân tiện, đối với những người bạn phát triển Android, tôi biết bạn nên sử dụng thuộc tính 'android: inputType' thay vì ... không ghét. –

0

Not about how good you code looks của nó, nhưng how good your code works .......... Ya offcourse it should be readable,Như nổi tiếng nói ...

Bất kỳ kẻ ngốc có thể viết một mã mà máy tính có thể hiểu được, nhưng chỉ lập trình viên vĩ đại viết mã mà con người có thể hiểu được.

Hoàn toàn tốt trong một số trường hợp, bạn cần phải có loại ngoại lệ như vậy.

When you want to catch multiple exceptions which belong to the same inheritance tree,then create a try block, and multiple catch blocks from more specific to moreabstract.

ví dụ:

`Animal <--- Carnivores <--- Dog` 

Bây giờ giả sử có một DogException, CarnivoresException, AnimalException.

Sau đó, nó phải như thế này,

try{ 

      // your code 

    } 
     catch(DogException d){} 
     catch(CarnivoresException c){} 
     catch(AnimalException a){} 

Trên sản lượng đánh bắt đã được cascaded từ cụ thể hơn để trừu tượng hơn để các ngoại lệ được bắt với nó rất nguyên nhân.

Nếu không có thừa kế, sau đó bắt có thể ở bất kỳ thứ tự ...

+1

Tôi cho rằng tuyên bố đầu tiên của bạn là đúng, tuy nhiên, hầu như tất cả các mã được sử dụng trong môi trường chuyên nghiệp sẽ có lỗi hoặc ban đầu hoặc khi nó được thêm vào. Do đó, mã của bạn trông đẹp như thế nào không quan trọng, hay đúng hơn, cách * có thể đọc được * mã của bạn là vấn đề. – BlackVegetable

1

Trong trường hợp của bạn tôi muốn một cái gì đó như một phương pháp isHexDigit để sử dụng NumberFormatException, trừ khi có một số giả định rằng bạn có thể thực hiện về định dạng dữ liệu của bạn - từ mô tả của bạn có vẻ như không có giả định như vậy về thời điểm bạn sẽ gặp phải số thập lục phân so với số không phải số hex.

Điều này là do ngoại lệ nên được sử dụng để xử lý điều kiện đặc biệt, và nếu sự mong đợi từ dữ liệu của bạn là: hai chữ số hex hoặc chữ số phi hex, cách nhau bằng dấu cách, sau đó không có gì đặc biệt về gặp một mã thông báo đó là khác với một chữ số hex.

Hơn nữa sử dụng ngoại lệ không làm cho mã ít đọc được hơn: không có nhận xét về dữ liệu, nó ẩn thực tế là các chữ số không phải là thập lục phân được chấp nhận và được nhập.

Sau khi đã nêu tùy chọn đó, tôi có thể sử dụng xử lý ngoại lệ để xử lý trường hợp này và tôi chắc chắn thấy nhiều mã thực hiện điều đó. Rất nhiều chức năng tốt được bao bọc cho bạn trong sự kết hợp của giải mã/parseInt/NumberFormatException. Tôi sẽ không sử dụng điều này nếu không có một nhận xét rõ ràng giải thích rõ ràng những gì tôi đang làm.

+0

"Xử lý ngoại lệ là tốt". Người khác đã hỏi trước đó ngày hôm nay đã khám phá ra một cách đơn giản nếu đơn giản là có một khối try/catch có thể được coi là "xấu xí". Không! Không gì có thể hơn được sự thật. Trong trường hợp đặc biệt này, tôi mạnh mẽ tin rằng một trình xử lý ngoại lệ vừa phù hợp ... vừa lý tưởng. Vì nhiều lý do khác nhau. IMHO ... – paulsm4

+0

PS: Tôi đồng ý với tuyên bố của bạn về "điều kiện đặc biệt". Một số người nghĩ rằng ngoại lệ chỉ nên được sử dụng cho "lỗi". Không: chúng có thể được sử dụng một cách hữu ích trong kịch bản * bất kỳ * không phù hợp với "dòng tiêu chuẩn". Điểm tốt ;)! – paulsm4

0

Tốt nhất bạn có thể làm. Một phương pháp hoặc là sẽ trả về một số loại thành công/chỉ báo lỗi hoặc nó sẽ ném một ngoại lệ, nó chỉ là một câu hỏi trong đó là thuận tiện nhất. Ở đây, Sun đã đưa ra quyết định cho chúng tôi, vì vậy không cần phải tranh luận.

Điều gì khiến tôi lo ngại về điều này là ngoại lệ sẽ bao gồm dấu vết ngăn xếp đầy đủ! Trong trường hợp cụ thể của bạn, nếu bạn đang đọc hàng triệu chuỗi này, bạn sẽ nhận thấy hiệu suất kém (hoàn toàn không cần thiết). Nếu nó quan trọng với bạn, bạn có thể muốn xem xét viết phương pháp của riêng bạn (bạn có thể sử dụng mã Sun như một hướng dẫn.) Sau đó, bạn có thể tự quyết định xem bạn có muốn sử dụng ngoại lệ hay không. Nếu bạn làm thế, hãy giữ một bản sao tĩnh của ngoại lệ tiện dụng và luôn ném nó để tiết kiệm thời gian phân bổ. Và ghi đè fillInStackTrace để nó không có gì và bạn không có dấu vết ngăn xếp vô nghĩa trong ngoại lệ của mình.

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