에서 주조 있는지 확인하기 위해 자바에서 가장 관용적 인 방법은 무엇 long
에이 int
정보를 잃지 않는다는?
이것은 내 현재 구현입니다.
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;
}
답변
이를 위해 Java 8 에 새로운 방법이 추가되었습니다 .
import static java.lang.Math.toIntExact;
long foo = 10L;
int bar = toIntExact(foo);
ArithmeticException
오버플 로 가 발생 하면 던질 것 입니다.
몇 가지 다른 오버 플로우 안전한 방법은 그들로 끝 자바 8에 추가 된 정확한 .
예 :
Math.incrementExact(long)
Math.subtractExact(long, long)
Math.decrementExact(long)
Math.negateExact(long),
Math.subtractExact(int, int)
답변
나는 다음과 같이 간단하게 할 것이라고 생각합니다.
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;
}
반복 캐스팅보다 의도를 더 명확하게 표현한다고 생각하지만 다소 주관적입니다.
잠재적 관심에 주목하십시오-C #에서는 다음과 같습니다.
return checked ((int) l);
답변
Google Guava의 Ints 클래스를 사용하면 메소드를 다음과 같이 변경할 수 있습니다.
public static int safeLongToInt(long l) {
return Ints.checkedCast(l);
}
연결된 문서에서 :
점검
public static int checkedCast(long value)
value
가능한 경우와 동일한 int 값을 반환 합니다.매개 변수 :
value
–int
유형 범위의 모든 값반환 값 :
int
값 같value
예외 :
IllegalArgumentException
–value
이보다 크Integer.MAX_VALUE
거나 작은 경우Integer.MIN_VALUE
또한 safeLongToInt
광범위한 리팩토링없이 기능을 변경하기 위해 래퍼를 남겨 두지 않는 한 래퍼 가 필요하지 않습니다 .
답변
BigDecimal로 :
long aLong = ...;
int anInt = new BigDecimal(aLong).intValueExact(); // throws ArithmeticException
// if outside bounds
답변
여기에 필요한 것보다 큰 경우 가치에 신경 쓰지 않는 경우 해결책이 있습니다.)
public static int safeLongToInt(long l) {
return (int) Math.max(Math.min(Integer.MAX_VALUE, l), Integer.MIN_VALUE);
}
답변
DONT : 이것은 해결책이 아닙니다!
내 첫 번째 접근 방식은 다음과 같습니다.
public int longToInt(long theLongOne) {
return Long.valueOf(theLongOne).intValue();
}
그러나 그것은 단지 long을 int로 캐스팅하여 잠재적으로 새로운 Long
인스턴스를 생성 하거나 Long 풀에서 검색 할 수 있습니다.
단점
-
Long.valueOf
Long
숫자가Long
풀 범위 [-128, 127] 내에없는 경우 새 인스턴스를 만듭니다 . -
intValue
구현은 다음을 수행합니다.return (int)value;
따라서 이것은 long
to에 캐스팅하는 것보다 더 나쁜 것으로 간주 될 수 있습니다 int
.
답변
값을 캐스팅하면 값이 변경되었는지 확인하는 확실한 방법은 캐스팅하고 결과를 확인하는 것입니다. 그러나 비교할 때 불필요한 캐스트를 제거합니다. 나는 또한 너무 한 문자 변수 이름에 예리한 (예외 아니에요 x
하고 y
있지만 때 평균 행과 열 (때로는 각각)).
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;
}
그러나 실제로 가능한 경우이 변환을 피하고 싶습니다. 분명히 가능하지는 않지만 IllegalArgumentException
클라이언트 코드와 관련하여 예외가 발생하는 것은 거의 확실합니다.