自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java中在時間戳計算的過程中遇到的數(shù)據(jù)溢出問題

開發(fā) 后端
今天在跑定時任務(wù)的過程中,發(fā)現(xiàn)有一個任務(wù)在設(shè)置數(shù)據(jù)的查詢時間范圍異常,出現(xiàn)了開始時間戳比結(jié)束時間戳大的奇怪現(xiàn)象,計算時間戳的代碼大致如下。

 背景

[[441841]]

今天在跑定時任務(wù)的過程中,發(fā)現(xiàn)有一個任務(wù)在設(shè)置數(shù)據(jù)的查詢時間范圍異常,出現(xiàn)了開始時間戳比結(jié)束時間戳大的奇怪現(xiàn)象,計算時間戳的代碼大致如下。

  1. package com.lingyejun.authenticator; 
  2.  
  3. public class IntegerTest { 
  4.  
  5.     public static void main(String[] args) { 
  6.         long endTime = System.currentTimeMillis(); 
  7.         long startTime = endTime - 30 * 24 * 60 * 60 * 1000; 
  8.  
  9.         System.out.println("end   : " + endTime); 
  10.         System.out.println("start : " + startTime); 
  11.     } 

先放出結(jié)論:因為java中整數(shù)默認是int類型,在計算的過程中30 * 24 * 60 * 60 * 1000計算結(jié)果大于Integer.MAX_VALUE,所以出現(xiàn)了數(shù)據(jù)溢出,從而導致了計算結(jié)果不準確的問題。

驗證

我們將上面的代碼稍稍改造一下,方便我們確認定位問題,調(diào)整后的代碼如下:

  1. package com.lingyejun.authenticator; 
  2.  
  3. public class IntegerTest { 
  4.  
  5.     public static long calcStartTime(long endTime, long minusMills) { 
  6.         System.out.println("end  : " + endTime + " minus mills : " + minusMills); 
  7.         long startTime = endTime - minusMills; 
  8.         System.out.println("start: " + startTime); 
  9.         return startTime; 
  10.     } 
  11.  
  12.     public static void main(String[] args) { 
  13.         long nowTime = System.currentTimeMillis(); 
  14.         long a = 30 * 24 * 60 * 60 * 1000; 
  15.         calcStartTime(nowTime, a); 
  16.     } 
  17. }   

結(jié)果如下:

  1. end  : 1560869539864 minus mills : -1702967296 
  2. start: 1562572507160 

這和我們的預期不一樣,因為30 * 86400000 = 2592000000,但是計算出來卻是:-1702967296。

到這里想必大家都知道原因了,這是因為java中整數(shù)的默認類型是整型int,而int的最大值是2147483647,

在代碼中java是先計算右值,再賦值給long變量的。在計算右值的過程中(int型相乘)發(fā)生溢出,然后將溢出后截斷的值賦給變量,導致了結(jié)果不準確。

將代碼做一下小小的改動,再看一下。

  1. package com.lingyejun.authenticator; 
  2.  
  3. public class IntegerTest { 
  4.  
  5.     public static long calcStartTime(long endTime, long minusMills) { 
  6.         System.out.println("end  : " + endTime + " minus mills : " + minusMills); 
  7.         long startTime = endTime - minusMills; 
  8.         System.out.println("start: " + startTime); 
  9.         return startTime; 
  10.     } 
  11.  
  12.     public static void main(String[] args) { 
  13.         long nowTime = System.currentTimeMillis(); 
  14.         long a = 30 * 24 * 60 * 60 * 1000L; 
  15.         calcStartTime(nowTime, a); 
  16.     } 

結(jié)果為

  1. end  : 1560869539864 minus mills : 2592000000 
  2. start: 1558277539864 

似乎這樣應(yīng)該就沒有什么問題了,但是這樣就真的保險了嗎,如果我要把30調(diào)整為24856(Integer.MAX_VALUE / 86400 = 24855),即改為:long a = 24856 * 24 * 60 * 60 * 1000L 那么同樣會出現(xiàn)溢出。

因為java的運算規(guī)則從左到右,再與最后一個long型的1000相乘之前就已經(jīng)溢出,所以結(jié)果也不對,正確的方式應(yīng)該如下:long a = 24856L * 24 * 60 * 60 * 1000。

  1. package com.lingyejun.authenticator; 
  2.  
  3. public class IntegerTest { 
  4.  
  5.     public static long calcStartTime(long endTime, long minusMills) { 
  6.         System.out.println("end  : " + endTime + " minus mills : " + minusMills); 
  7.         long startTime = endTime - minusMills; 
  8.         System.out.println("start: " + startTime); 
  9.         return startTime; 
  10.     } 
  11.  
  12.     public static void main(String[] args) { 
  13.         long a = 30L * 24 * 60 * 60 * 1000; 
  14.         calcStartTime(nowTime, a); 
  15.     } 

 

責任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2021-03-06 10:25:19

內(nèi)存Java代碼

2021-02-03 15:12:08

java內(nèi)存溢出

2016-03-23 11:03:40

2010-05-11 18:05:50

MySQL 5安裝

2022-03-25 09:01:16

CSS溢出屬性

2009-12-10 14:19:41

配置靜態(tài)路由

2023-02-28 16:26:46

推薦系統(tǒng)模塊

2020-07-29 08:03:26

Celery異步項目

2023-08-29 11:38:27

Java內(nèi)存

2010-09-27 13:45:38

2015-07-09 10:36:40

iOS

2010-09-26 15:53:25

JVM內(nèi)存溢出

2024-09-09 08:02:27

2019-10-28 14:07:29

研發(fā)管理技術(shù)

2011-04-11 13:28:31

Oracle安裝

2021-08-05 08:32:27

React開發(fā)項目

2012-02-14 13:39:57

Java

2021-11-15 15:43:28

Windows 11升級微軟

2011-04-11 13:25:59

Sybase安裝

2010-01-04 18:25:24

Ubuntu Auda
點贊
收藏

51CTO技術(shù)棧公眾號