Java에서 안전하게 int에 캐스팅
자바에서 가장 관용적인 방법으로 캐스트를 검증할 수 있는 것은?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
오버플로우일 경우.
참조:
Java 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)
다음과 같은 int 값을 반환합니다.
value
,가능하면.파라미터:
value
- 의 범위 내의 임의의 값int
유형반품:
int
같은 값value
던지기:
IllegalArgumentException
- 만약value
보다 크다Integer.MAX_VALUE
이하Integer.MIN_VALUE
덧붙여서, 당신은 그 일을 할 필요가 없다.safeLongToInt
물론 광범위한 리팩터링 없이 기능을 변경하기 위해 래퍼를 그대로 두는 것이 바람직하지 마십시오.
Big Decimal의 경우:
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);
}
이건 해결책이 아니야!
첫 번째 접근법은 다음과 같습니다.
public int longToInt(long theLongOne) {
return Long.valueOf(theLongOne).intValue();
}
하지만 그것은 단지 장황한 것을 int에 던져넣을 뿐이고 잠재적으로 새로운 것을 만들어 낼 수 있다.Long
인스턴스 또는 롱 풀에서 인스턴스를 검색합니다.
결점
Long.valueOf
신규 생성Long
번호가 범위 내에 없는 경우 인스턴스Long
의 풀 범위 [-128, 127]그
intValue
구현은 다음 작업만 수행합니다.return (int)value;
그래서 이건 그냥 연기하는 것보다 더 나쁜 것으로 여겨질 수 있어long
로.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
클라이언트 코드에 관한 한 잘못된 예외는 거의 확실합니다.
Java 정수형은 부호 있는 것으로 표시됩니다.2와32 2 사이의 입력31(또는31 -2와 -232)을 사용하면 캐스팅은 성공하지만 검정은 실패합니다.
해야 할 것은 '고비트'의가 '고비트'인지 입니다.long
모두 동일합니다.
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("...");
}
}
(int) (longType + 0)
단, Long은 최대값을 초과할 수 없습니다.
또 하나의 솔루션은 다음과 같습니다.
public int longToInt(Long longVariable)
{
try {
return Integer.valueOf(longVariable.toString());
} catch(IllegalArgumentException e) {
Log.e(e.printstackstrace());
}
}
클라이언트가 POST를 실행하고 서버 DB가 Integress만 인식하는 경우 Long이 있는 경우 이 방법을 사용해 보았습니다.
언급URL : https://stackoverflow.com/questions/1590831/safely-casting-long-to-int-in-java
'programing' 카테고리의 다른 글
ES6 함수의 구문 (0) | 2022.08.27 |
---|---|
Control+D 신호를 캡처하는 방법 (0) | 2022.08.27 |
memcpy(0,0,0)를 실행해도 안전한가? (0) | 2022.08.27 |
VueJ: mapGetters 수신 인수를 통해 상태 변경에 대응 (0) | 2022.08.27 |
Vuex: 계산된 속성이 정의되지 않음 - asyc Axios (0) | 2022.08.27 |