1. 변하는 변수 변하지 않는 변수
변수: 변하는 저장공간
상수: 변하지 않는 저장공간
2. 변수의 종류
2.1 기본형 변수 vs 참조형 변수
2.1.1 기본형 변수의 종류
● 논리형 변수 boolean
○ True/False 값만 저장한다.
boolean flag = true; // 1. 논리형 변수 boolean 으로 선언 및 True 값으로 초기화
flag = false; // 2. False 값으로도 저장할 수 있습니다.
● 문자형 변수 char
○ 'a', '1'와 같은 문자 하나만 저장한다.
char alphabet = 'A'; // 문자 하나를 저장합니다.
● 정수형 변수 byte, short, int, long
○ 0, 13, 999 와 같은 정수형 숫자를 저장한다.
- byte : -128 ~ 127 범위의 숫자만 저장 가능합니다.
- short (2byte) 는 -32,768~32,767 범위의 숫자만 저장 가능합니다.
- int (4byte) 는 -21억~21억 범위의 숫자만 저장 가능합니다.
- long (8byte) 은 9백경 정도의 매우 큰수를 저장 가능합니다.
byte byteNumber = 127; // byte 는 -128 ~ 127 범위의 숫자만 저장 가능합니다.
short shortNumber = 32767; // short 는 -32,768~32,767 범위의 숫자만 저장 가능합니다.
int intNumber = 2147483647; // int 는 -21억~21억 범위의 숫자만 저장 가능합니다.
long longNumber = 2147483647L; // long 은 숫자뒤에 알파벳 L 을 붙여서 표기하며 매우 큰수를 저장 가능합니다.
● 실수형 변수 float, double
○ 0.0, 0.1, 0.999 와 같은 실수형 숫자를 저장한다.
※실수형 변수는 정수형 변수보다 같은byte를 이용하여도 표현범위가 매우 크기때문에 정수가 담지 못할 수 있다.
float (4byte) : -3.4 * 10^38 ~ 3.4 * 10^38(long 보다 큼)범위의 숫자 저장이 가능합니다.
double(8byte) : -1.7 * 10^308 ~ 1.7 * 10^38(long 보다 큼)범위의 숫자 저장이 가능합니다.
float floatNumber = 0.123f; // float 는 4byte 로 3.4 * 10^38 범위를 표현하는 실수값
double doubleNumber = 0.123123123; // double 은 8byte 로 1.7 * 10^308 범위를 표현하는 실수값
2.1.2 참조형 변수의 종류
● 문자형 변수 String
○ "Apple", "Banana"와 같은 문자을 저장한다.
String message = "Hello World"; // 문자열을 저장합니다.
● 그 외, Object, Array, List ...
○ 객체, 배열, 리스트와 같은 단일 저장공간에 담을 수 없는 값을 저장합니다.
List<int> alphabet = [0,1,2,3]; // 기본형 변수 여러개를 저장합니다.
3. 기본형 변수와 참조형 변수의 저장관점에서 차이점
기본형 변수는 메모리의 Stack영역에 실제 값을 저장한다면 참조형은 Heap영역에 실제 값을 저장하고 해당 주소를 stack에 저장하는 방식을 사용한다.
Stack영역의 경우는 정적으로 할당된 메모리 영역으로 크기가 정해져있는 기본형 변수를 저장한다. 또한 크키가 정해져있는 참조형 변수의 주소값도 저장한다.
Heap영역의 경우에는 동적으로 할당된 메모리 영역으로 크기가 계속 늘어날 수 있는 참조형 변수의 원본을 저장한다.
3.1 얕은복사 vs 깊은복사
얕은복사란 주소값을 복사하는것을 의미하며 주소값을 복사하기때문에 참조하고있는 실제 값(Heap영역의)은 같다.
public class Main {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b = a;
b[1] = 10;
System.out.println(a[1]);
}
}
//실행결과
//10
위 코드에서 int형 배열 a를 선언과함께 1,2,3,4,5로 초기화했고 int형 배열 b는 a를 얕은 복사하였다.
b배열의 1번째 인덱스의 값을 10으로 바꿨고 a[1]의 값을 출력했더니 a배열의 값은 변경한적이 없지만 10으로 바뀐것을 볼 수 있다.
이는 a배열은 Heap영역에 있는 실제 값의 주소값을 저장하고있었고 b배열은 a를 복사하였기 때문에 결과적으로는 같은 Heap영역의 실제값을 가리키고있다. 이러한 상황에서 배열b가 값을 변경하니 같은곳을 가리키던 배열a를 출력했을때 변경된 값이 출력되었다.
이와 반대로 깊은복사는 '실제 값'을 새로운 메모리 공간에 복사하는것을 의미한다.
public class Main {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);
b[1] = 10;
System.out.println("a[1] = " + a[1]);
System.out.println("b[1] = " + b[1]);
}
}
//a[1] = 2
//b[1] = 10
위 코드에서는 Arrays.copyOf()을 통해 깊은 복사를 하였고 메모리에 a배열이 가리키고 있는 Heap영역의 실제 값을 복사해 새로운 메모리 공간에 복사하였다.
때문에 b배열의 값을 변경하여도 a배열의 값은 바뀌지 않았다.
'언어 > JAVA' 카테고리의 다른 글
[TIL]20230622 - 예외처리 (0) | 2023.06.22 |
---|---|
[TIL]20230620 - 상속과 다형성 (0) | 2023.06.21 |
[TIL]20230615 - 스트림의 toList()가 없다 (2) | 2023.06.16 |
[TIL]20230613 - HashSet 의 저장방법 (0) | 2023.06.14 |
[Java]자바의 장점, JVM, JRE, JDK (0) | 2023.06.12 |