Java-참조변수, 메모리 영역
데이터의 분류
- 기본타입 : 정수, 실수, 논리 타입
-
참조타입 : 배열, 열거, 클래스, 인터페이스 - 중요
- 기본타입 vs 참조타입 - 차이점
- 해당 타입으로 선언된 변수에 어떤 값을 저장하는가?
- 기본타입 → 실제 데이터 (0, true, 4.225 등등)
- 참조타입 → 메모리의 번지, 주소를 통해 객체를 참조
- 스택영역엔 변수a와 메모리주소 0001이 저장되고 JAVA는 힙영역에 저장됨
자바의 메모리 영역 (크게 3가지)
- 메소드영역 → 메소드와 클래스 데이터를 저장하기 위한 공간.
- 힙영역 → 동적으로 할당하여 사용할 수 있는 메모리, 주로 Runtime으로 생성되는 객체를 저장
- 스택영역 → 메소드 호출 시 메소드의 매개변수, 지역변수, 임시변수 등을 저장하기 위한 스택구조의 메모리 실행 중인 프로그램에 따라 스택 프레임 할당.
스택이란? (=바구니)
Last In First Out
메모리 상의 변수들의 값
int age = 25;
double price = 100.5;
String name = "김명관";
String hobby = "game";
스택영역에 저장 된것
game | 500번지 |
---|---|
name | 1000번지 |
price | 100.5 |
age | 25 |
참조타입 변수
- 기본타입처럼 스택영역에 직접 값을 가지고 있는게 아니라 참조타입은 힙영역의 객체 주소를 스택영역에 가지고 있음.
- 참조변수의 ==, != 연산
- 똑같은 “김명관”을 두 개 생성해도 ==는 김명관이 아니라 김명관이 저장되어있는 주소값이 같은지 여부를 비교한다.
- 동일한 객체를 참조하는지, 다른 객체를 참조하는지를 알아 볼 때 사용한다. String str1 = “김명관”; String str2 = “김명관”;
- 문자열은 String객체로 생성되고 변수는 String 객체를 참조함. 자바에서는 문자열 리터럴이 동일하다면 String 객체를 공유함.
- new연산자 : 힙영역에 새로운 객체를 만들 때 사용하는 연산자 = 객체 생성 연산자
String str3 = new String("김명관");
- 참조 타입변수는 힙영역의 객체를 참조하지 않았다는 뜻으로 null값을 가질 수 있음.
String str4; //이게 null값
- 만약에 str4의 길이찾는 str4.length();를 사용하면 NullPointerException 오류가 뜸 → 찾아갈 주소가 없다는 뜻.
배열
int[] intArray = new int[3]; // 빈 배열 만들기 int[] students = { 1, 5, 5, 6, 546, 546, 516523 }; int [] lotto = new int [6]; for (int i = 0; i < lotto.length; i++) { lotto[i] = (int) (Math.random() * 45 + 1); } for (int e : lotto) { System.out.println(e); }
- 1번줄
- 선언만 하고 초기화를 안한 상태이지만 배열의 길이는 설정되어있음. 다 0으로 저장되어있음.
- 값의 목록은 가지고 있지는 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new연산자로 배열 객체를 생성할 수 있음.
- 이렇게 new연산자로 배열을 생성하면 기본값으로 초기화됨. (int → 0, String → null)
- 2번줄
- 선언과 동시에 초기화까지 시켜놓은 상태.
- 저장 프로세스
- 주어진 값들을 항목으로 가지는 배열을 힙영역에 생성하고
- 배열 객체의 번지(주소)를 가져온다.
- 배열 변수(students)는 가져온 주소값을 저장함으로써 나중에 참조할 수 있게됨. 배열도 객체이므로 힙영역에 생성되고 배열변수는 힙영역의 배열객체를 참조한다.
- 3~9번줄
- 이런 식으로 배열을 이용한 for-each구문 사용가능.
- Math.random() 객체는 0 <= x <1 까지의 임의의 숫자를 가져다줌.
- 배열복사
- 얕은 복사 : 객체 주소값을 복사 (한번 복사하면 둘 다 값이 자동으로 바뀌어버림.)
int[]arr=new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3; int[]arr2= null; arr2 = arr; //객체 주소값을 복사
- 깊은 복사 : 구체적인 값을 복사 (복사를 해도 서로 다른 주소값이므로 변경해도 값은 다른 한 쪽이 자동으로 안 바뀜.)
int[]arr=new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3; int[]arr=new int[3]; for (int e : arr) { System.out.print(e + ", "); }
- 얕은 복사 : 객체 주소값을 복사 (한번 복사하면 둘 다 값이 자동으로 바뀌어버림.)
댓글남기기