Mục lục
Java ném ra NumberFormatException – một uncheck exception – khi nó không thể chuyển đổi một string thành một số. Trong hướng dẫn nhanh này, chúng ta sẽ tìm hiểu và giải thích nguyên nhân gây ra NumberFormatException trong Java và cách tránh hoặc xử lý nó.
Nguyên nhân gây ra NumberFormatException
Có nhiều nguyên nhân khác nhau gây ra NumberFormatException mà chúng ta sẽ cùng thảo luận ngay sau đây.
Dữ liệu không phải dạng số truyền vào Constructor
Hãy xem constructor của Integer và Double wrapper class chuyển đổi một string sang số tương ứng
Integer aIntegerObj = new Integer("one"); Double doubleDecimalObj = new Double("two.2");
Xem stack trace in ra chúng ta có thể thấy rằng string “one” trong Integer constructor là một string không hợp lệ
Exception in thread "main" java.lang.NumberFormatException: For input string: "one" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.<init>(Integer.java:867) at MainClass.main(MainClass.java:11)
Java không phân tích một chuỗi có ngữ nghĩa sang số mà nó chỉ hoạt động trên những con số thực được biểu diễn dưới dạng string.
Integer aIntegerObj = new Integer("1"); Double doubleDecimalObj = new Double("2.2");
Dữ liệu không phải dạng số truyền vào method
Tương tự như Java hỗ trợ chuyển string thành number trong constructor chúng ta có các phương thức chuyên dụng như parseInt (), parseDouble (), valueOf () và decode () có thể dùng để chuyển từ string sang number.
Ví dụ đoạn code dưới đây cũng sẽ gây ra NumberFormatException
int aIntPrim = Integer.parseInt("two"); double aDoublePrim = Double.parseDouble("two.two"); Integer aIntObj = Integer.valueOf("three"); Long decodedLong = Long.decode("64403L");
Và chúng ta có thể sửa như sau:
int aIntPrim = Integer.parseInt("2"); double aDoublePrim = Double.parseDouble("2.2"); Integer aIntObj = Integer.valueOf("3"); Long decodedLong = Long.decode("64403");
Chuỗi chứa các ký tự lạ
Hoặc, nếu chúng ta cố gắng chuyển đổi một string thành number có các dữ liệu không liên quan trong input, như khoảng trắng hoặc các ký tự đặc biệt:
Short shortInt = new Short("2 "); int bIntPrim = Integer.parseInt("_6000");
Trong trường hợp này, chúng ta sẽ gặp vấn đề tương tự như trên. Chúng ta có thể sửa những điều này bằng một chút thao tác chuỗi:
Short shortInt = new Short("2 ".trim()); int bIntPrim = Integer.parseInt("_6000".replaceAll("_", "")); int bIntPrim = Integer.parseInt("-6000");
Lưu ý ở đây trong dòng 3 rằng số âm được phép sử dụng ký tự gạch nối làm dấu trừ.
Định dạng số cụ thể theo ngôn ngữ
Chúng ta hãy xem một trường hợp đặc biệt của các con số theo ngôn ngữ địa phương. Ở các khu vực Châu Âu, dấu phẩy có thể thể hiện vị trí thập phân. Ví dụ: “4000,1” có thể đại diện cho số thập phân “4000.1”.
Theo mặc định, chúng ta sẽ nhận NumberFormatException khi input chứa môt dấu phẩy
double aDoublePrim = Double.parseDouble("4000,1");
Chúng ta cần giúp cho Java hiểu dấu phẩy là là biểu diễn dạng thâp phân. Để làm được điều này, Java cần hiểu dấu phẩy ở đây là phần thập phân. Để làm được điều này, chúng ta cần chỉ khu vực cụ thể như sau
NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE); Number parsedNumber = numberFormat.parse("4000,1"); assertEquals(4000.1, parsedNumber.doubleValue()); assertEquals(4000, parsedNumber.intValue());
Best Practices
Chúng ta có một số phương pháp cụ thể để giảm thiểu tối đa việc nhận phải một NumberFormatException:
- Đừng cố chuyển đổi các ký tự chữ cái hoặc ký tự đặc biệt thành số – Java Number API không thể làm điều đó.
- Kiểm tra tính hợp lệ của dữ liệu đầu vào trước khi thực hiện việc chuyển đổi.
- Chuẩn hoá dữ liệu đầu vào như xoá bỏ khoảng trắng đầu và cuối chuỗi – trim(), loại bổ các ký tự đặc biệt – replace(), replaceAll().
- Trong một số trường hợp, các ký tự đặc biệt trong dữ liệu đầu vào có thể hợp lệ. Chúng ta có thể sử dụng NumberFormat hỗ trợ các định dạng khác nhau.
Kết bài
Trong hướng dẫn này, chúng ta đã thảo luận về NumberFormatException trong Java và nguyên nhân gây ra nó. Hiểu ngoại lệ này có thể giúp chúng tôi tạo ra các ứng dụng mạnh mẽ hơn.
Hơn nữa, chúng ta đã học các chiến lược để tránh ngoại lệ với một số chuỗi đầu vào không hợp lệ.
Cuối cùng, chúng ta có một số phương pháp hay để xử lý NumberFormatException.
Nguồn tham khảo