오버플로우와 언더플로우
- 오버플로우 : 타입의 최대 허용범위를 벗어나는 것
- 언더플로우 : 타입의 최소 허용범위를 벗어나는 것
정수 타입 연산에서 오버플로우가 발생하면 컴파일 에러가 발생하지 않고, 해당 타입의 최솟값으로 돌아가서 순환한다. 마찬가지로 언더플로우가 발생하면 해당 타입의 최댓값으로 돌아가서 순환한다.
예를 들어 byte 타입의 허용범위는 -128~127인데 127을 넘어가는 오버플로우가 발생하면, 최솟값으로 돌아가 -128부터 순환한다. 언더플로우도 마찬가지로 127로 돌아가서 순환한다.
byte value = 127;
value++;
System.out.println(value); //-128
value--;
System.out.println(value); //127
다른 정수 타입의 경우에도 마찬가지이다. 따라서 연산과정에서 오버플로우와 언더플로우가 발생하지 않게 알맞은 타입을 지정해줘야한다.
기본타입의 해시코드
//어제
int x = 3;
int y = 3;
System.out.println(System.identityHashCode(x)); //356573597
System.out.println(System.identityHashCode(y)); //356573597
//오늘
int x = 3;
int y = 3;
System.out.println(System.identityHashCode(x)); //2003749087
System.out.println(System.identityHashCode(y)); //2003749087
같은 변수에 같은 값인데 어제의 해시코드와 다르다. JVM이 메모리를 정리한 후라서 해시코드가 다른 것 같다. 또한 기본타입에서는 메모리 주소값이 부여되는 방식이 물리적인 변수의 모양과 값의 형태와는 상관이 없는 것 같다.
int x = 5;
int y = 3;
System.out.println(System.identityHashCode(x)); //2003749087
System.out.println(System.identityHashCode(y)); //1324119927
변수는 그대로 유지시키고 x의 값만 변경한 결과, y가 참조하는 메모리 주소 값만 바뀐 것을 확인할 수 있다.
이로 인해 알 수 있는 사실은 컴파일러가 가장 먼저 읽은 변수를 값과 함께 먼저 메모리에 올리면서 번지를 부여하고, 그다음 메모리에 올라가는 변수의 값을 먼저 메모리에 올린 값과 비교해 본 후 값이 같다면 먼저 올라간 변수와 같은 번지를 부여하고, 다르다면 다른 번지수를 부여한다는 것이다.
결론은 먼저 메모리에 올라간 변수가 어떤 값을 가지고 있는지가 뒤에 올 변수들의 메모리 번지에 영향을 준다는 것이다.
따라서 int형 변수 x, y, z가 초기값과 함께 소스코드에 순차적으로 있을 때 x의 값이 y의 값과 같다면 x, y의 해시코드값은 같고, z의 해시코드만 다르다.
y와 z의 값이 같다면 x의 해시코드만 다르고, y와 z의 해시코드는 같다.
세 변수의 값이 같다면 모두 같은 해시코드를 갖게 된다.
int x = 2;
int y = 2;
int z = 3;
System.out.println(System.identityHashCode(x)); //2003749087
System.out.println(System.identityHashCode(y)); //2003749087
System.out.println(System.identityHashCode(z)); //1324119927
x = 3;
y = 2;
z = 2;
System.out.println(System.identityHashCode(x)); //1324119927 : 전z변수의 값과 같기때문에 해시코드가 같다
System.out.println(System.identityHashCode(y)); //2003749087
System.out.println(System.identityHashCode(z)); //2003749087
x = 2;
y = 2;
z = 2;
System.out.println(System.identityHashCode(x)); //2003749087 : 전z변수의 값과 같기때문에 해시코드가 같다
System.out.println(System.identityHashCode(y)); //2003749087
System.out.println(System.identityHashCode(z)); //2003749087
'Back-End > Java' 카테고리의 다른 글
Java 예습 (0) | 2023.03.11 |
---|---|
Java 예습 (0) | 2023.03.04 |
java.base 모듈 (0) | 2023.01.19 |
댓글