Poiché il secondo valore utilizza uno integer
non uno long
e ha overflow.
Se aggiungi una L alla fine di una delle due costanti, la cambierà utilizzando i valori long
e la differenza sparirà.
Questo perché nel secondo esempio entrambi i valori sono numeri interi. int * int = int. Viene promosso a long anche se uno o più valori moltiplicati (o qualsiasi altra operazione matematica per quella materia) è lungo. Non esiste una "magia" che rileva l'overflow e fa la promozione per te.
Anche se è stato effettuato long x = int*int
, continuerà a moltiplicare in 32 bit e quindi convertire il risultato in 64 bit per l'assegnazione.
Si può anche vedere questo in luoghi più sottili troppo - ad esempio:
long l;
int x,y;
long result = l+x*y;
Anche se risultato e l sono entrambi a lungo, la x * y è ancora stato fatto come interi poiché la moltiplicazione è fatta per prima . Anche se x e y si adattano individualmente in un intero a 32 bit, se il prodotto dei due non si verifica in una situazione di overflow. La correzione è quello di assicurarsi che il suo convertito in lunga al più presto punto in cui si esegue in rischio troppo pieno - per esempio:
long result = l+((long)x)*y;
fonte
2013-12-10 13:18:34
@Vlad: Che 'L' nel primo argomento è significativo, si vede. Prova 'System.out.println (1386633600 * 1000)' e guarda cosa ottieni ... –
@Vlad Il compilatore java non esegue l'inferenza del tipo, e il controllo del tipo va in altro modo di quanto pensi: prima risolve il tipo dell'espressione, quindi seleziona il metodo appropriato per tale espressione. In tal caso, ha un 'int' e quindi il costruttore' Date (long) 'è la soluzione migliore. (Non importa se il metodo non è affatto sovraccarico). – Ingo