Một ghi chú nhỏ về kiểu dữ liệu trong Java - v9bet999
Gần đây, tôi đã phát hiện ra một vấn đề thú vị. Cùng xem đoạn mã sau đây:
1public static void main(String[] args) {
2 Integer motTramNam = 36500;
3 System.out.println(motTramNam * 24 * 60 * 60 * 1000);
4}
Đoạn mã này định nghĩa một biến để biểu thị thời gian của 100 năm và tính toán giá trị thời gian tương ứng. Kết quả đầu tiên mà chúng ta nhận được là:
11094004736
Nếu bạn không quen thuộc với các giá trị thời gian (timestamp), có thể bạn sẽ không nhận thấy vấn đề gì ở đây. Tuy nhiên, điều kỳ lạ là kết quả cuối cùng không đúng như mong đợi, mặc dù nó đã nhân với 1000. Phần đuôi kết quả là 736, nhưng chúng ta chưa cần lo lắng về điều đó ngay bây giờ.
Tiếp theo, hãy thêm một số tính toán khác vào đoạn mã:
1public static void main(String[] args) {
2 Integer motTramNam = 36500;
3 System.out.println(motTramNam * 24 * 60 * 60 * 1000);
4 System.out.println(System.currentTimeMillis() + motTramNam * 24 * 60 * 60 * 1000);
5}
Kết quả mà chúng ta thu được là:
11094004736
21726195843465
Khi kiểm tra timestamp này, chúng ta phát hiện rằng thay vì chỉ ra ngày 31 tháng 8 năm 2124 (như chúng ta mong đợi), nó lại cho ra một ngày cách hiện tại chỉ khoảng 12 ngày! Điều này rõ ràng hoàn toàn sai so với khoảng thời gian 100 năm mà chúng ta đã định nghĩa. Vậy lý do là gì? Những người am hiểu có lẽ sẽ nhìn ra ngay rằng đây là vấn đề liên quan đến việc chuyển đổi kiểu dữ liệu.
Hãy thử sửa mã bằng cách sử dụng kiểu long
:
1public static void main(String[] args) {
2 Integer motTramNam = 36500;
3 System.out.println(motTramNam * 24 * 60 * 60 * 1000L);
4 System.out.println(System.currentTimeMillis() + motTramNam * 24 * 60 * 60 * 1000L);
5}
Hoặc dùng phương pháp khác:
1public static void main(String[] args) {
2 Integer motTramNam = 36500;
3 System.out.println(Long.valueOf(motTramNam * 24 * 60 * 60 * 1000));
4 System.out.println(System.currentTimeMillis() + Long.valueOf(motTramNam * 24 * 60 * 60 * 1000));
5}
Tuy nhiên, cả hai cách trên vẫn dẫn đến kết quả sai. Lý do nằm ở thời điểm thực hiện chuyển đổi kiểu dữ liệu. Để hiểu rõ hơn, chúng ta hãy ketquabongdatructuyen xem xét ví dụ sau:
1public static void main(String[] args) {
2 Integer motTramNam = 36500;
3 System.out.println(motTramNam * 24);
4 System.out.println(motTramNam * 24 * 60);
5 System.out.println(motTramNam * 24 * 60 * 60);
6 System.out.println(motTramNam * 24 * 60 * 60 * 1000);
7}
Kết quả là:
1876000
252560000
3-1141367296
41094004736
Chúng ta có thể thấy rằng khi nhân với con số thứ hai là 60, kết quả đã trở thành âm. Nguyên nhân là vì giá trị vượt quá tin tức bóng đá phạm vi của kiểu Integer
. Nhưng tại sao khi chúng ta chuyển sang sử dụng kiểu long
, kết quả vẫn sai?
Điều này liên quan đến cách biên dịch viên xử lý việc chuyển đổi kiểu dữ liệu. Khi hai giá trị kiểu Integer
được nhân với nhau, biên dịch viên coi đây là phép nhân giữa hai số nguyên (int
) và không kiểm tra giới hạn của kết quả. Chỉ khi gặp số 1000 được khai báo rõ ràng là kiểu long
(1000L), biên dịch viên mới thực hiện việc chuyển đổi kiểu dữ liệu.
Để giải quyết vấn đề này, chúng ta chỉ cần đảm bảo rằng ít nhất một phần tử trong chuỗi phép nhân được khai báo là kiểu long
từ sớm. Ví dụ:
1System.out.println(motTramNam.longValue() * 24 * 60 * 60 * 1000);
Như vậy, bài học rút ra là: khi làm việc với các phép tính lớn, cần đặc biệt chú ý đến việc quản lý các kiểu dữ liệu và thời điểm chuyển đổi. Đôi khi, việc chỉ thêm hậu tố L
vào cuối không đủ để giải quyết vấn đề nếu các phép toán trước đó đã vượt quá giới hạn của kiểu int
.
Hy vọng bài viết này giúp ích cho bạn trong việc hiểu rõ hơn về việc xử lý các kiểu dữ liệu trong Java!