Bezpiecznie rzucać long do int w Javie
Jaki jest najbardziej idiomatyczny sposób w Javie, aby sprawdzić, czy Obsada od long
do int
nie traci żadnych informacji?
To jest moja obecna implementacja:
public static int safeLongToInt(long l) {
int i = (int)l;
if ((long)i != l) {
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
}
return i;
}
10 answers
Została dodana nowa metoda zJava 8 w tym celu.
import static java.lang.Math.toIntExact;
long foo = 10L;
int bar = toIntExact(foo);
Rzuci ArithmeticException
w przypadku przepełnienia.
Zobacz: Math.toIntExact(long)
Do Java 8 dodano kilka innych bezpiecznych metod przepełnienia. Kończą się na dokładnie .
Przykłady:
Math.incrementExact(long)
Math.subtractExact(long, long)
Math.decrementExact(long)
Math.negateExact(long),
Math.subtractExact(int, int)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 23:32:48
Myślę, że zrobiłbym to tak po prostu:
public static int safeLongToInt(long l) {
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw new IllegalArgumentException
(l + " cannot be cast to int without changing its value.");
}
return (int) l;
}
Myślę, że to wyraża intencję wyraźniej niż powtarzający się casting... ale to trochę subiektywne.
Uwaga o potencjalnym zainteresowaniu-w C# byłoby po prostu:
return checked ((int) l);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-11 17:24:17
Z klasą Ints twoja metoda może zostać zmieniona na:
public static int safeLongToInt(long l) {
return Ints.checkedCast(l);
}
Z linked docs:
CheckedCast
public static int checkedCast(long value)
Zwraca wartość int, która jest równa
value
, jeśli to możliwe.Parametry:
value
- dowolna wartość z zakresu typuint
Zwraca: wartość
int
równa sięvalue
Rzuca:
IllegalArgumentException
- jeżeli {[2] } jest większa niżInteger.MAX_VALUE
lub mniej niżInteger.MIN_VALUE
Nawiasem mówiąc, nie potrzebujesz wrappera safeLongToInt
, chyba że chcesz go zostawić na swoim miejscu, aby zmienić funkcjonalność bez rozbudowanej refaktoryzacji, oczywiście.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-29 13:35:53
Z BigDecimal:
long aLong = ...;
int anInt = new BigDecimal(aLong).intValueExact(); // throws ArithmeticException
// if outside bounds
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-04 13:23:35
Oto rozwiązanie, jeśli nie zależy ci na wartości, jeśli jest ona większa niż potrzebna;)
public static int safeLongToInt(long l) {
return (int) Math.max(Math.min(Integer.MAX_VALUE, l), Integer.MIN_VALUE);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-10 21:33:53
DONT: to nie jest rozwiązanie!
Moje pierwsze podejście było:
public int longToInt(long theLongOne) {
return Long.valueOf(theLongOne).intValue();
}
Ale to tylko rzuca long do int, potencjalnie tworząc nowe instancje Long
lub pobierając je z długiej puli.
Wady
Long.valueOf
tworzy nową instancjęLong
, jeśli liczba nie mieści się w zakresie puliLong
[-128, 127].-
Implementacja
intValue
nie robi nic więcej niż:return (int)value;
Więc to można uznać nawet za gorsze niż samo rzucanie long
na int
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-02 11:21:15
Twierdzę, że oczywistym sposobem sprawdzenia, czy rzucanie wartości zmieniło wartość, byłoby rzucenie i sprawdzenie wyniku. Ja jednak przy porównywaniu usunąłbym niepotrzebny gips. Nie przepadam też za jednoliterowymi nazwami zmiennych (wyjątek x
i y
, ale nie wtedy, gdy oznaczają one wiersz i kolumnę (czasami odpowiednio)).
public static int intValue(long value) {
int valueInt = (int)value;
if (valueInt != value) {
throw new IllegalArgumentException(
"The long value "+value+" is not within range of the int type"
);
}
return valueInt;
}
Jednak naprawdę chciałbym uniknąć tego nawrócenia, jeśli w ogóle jest to możliwe. Oczywiście czasami nie jest to możliwe, ale w tych przypadkach {[3] } jest prawie z pewnością błędnym wyjątkiem jest rzucanie, jeśli chodzi o kod klienta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-19 20:22:37
Typy liczb całkowitych Javy są reprezentowane jako Podpisane. Z wejściem pomiędzy 231 oraz 232 (lub -231 oraz -232) Obsada by się powiodła, ale twój test by się nie powiódł.
Należy sprawdzić, czy wszystkie wysokie bity long
są takie same:
public static final long LONG_HIGH_BITS = 0xFFFFFFFF80000000L;
public static int safeLongToInt(long l) {
if ((l & LONG_HIGH_BITS) == 0 || (l & LONG_HIGH_BITS) == LONG_HIGH_BITS) {
return (int) l;
} else {
throw new IllegalArgumentException("...");
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-19 20:39:41
(int) (longType + 0)
Ale długo nie może przekroczyć maksimum:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-06 08:23:38
Innym rozwiązaniem może być:
public int longToInt(Long longVariable)
{
try {
return Integer.valueOf(longVariable.toString());
} catch(IllegalArgumentException e) {
Log.e(e.printstackstrace());
}
}
Próbowałem tego w przypadkach, gdy klient robi POST i serwer DB rozumie tylko liczby całkowite, podczas gdy Klient ma długi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-03 09:22:47