JVM - 자바 가상 머신
메소드(함수) 영역
기본적으로 함수 코드가 올라가는 영역
모든 함수 코드는 메모리 공간에 올라가고 메모리 주소값을 가짐.
힙 영역
기본 타입 8개(int,double,..등) 을 제외한 모든 나머지(객체, 배열 등) 가 모두 힙 영역에 저장
사용되지 않는 객체는 Garbage Collector 가 자동제거
힙 영역에 만들어지는 것은 참조 대상(실제 객체가 힙에 저장). 직접적으로 조작할 수 없는 영역.
직접 조작이 불가능하기 때문에, 간접적으로 주소를 받아와서 참조타입 변수를 간접적으로 사용한다. (c++ 에서는 포인터나 페러런스로 간접적으로 사용)
스레드 영역 (스택 영역)
스레드 영역 안에 들어있는게 스택 영역임
스레드 하나에서 메인 함수를 돌리고, 코드 상에서 만든 변수들이 모두 스택 위에 올라감.
int a, int double 을 만들면 이 기본타입 변수들은 모두 스택에 올라감
그러나, string s 를 만들면 기본 타입이 아니고, 스택 영역에 s라는 이름을 가진 참조변수가 올라가고, 실제 객체는 힙 영역에 만들어지고 s는 힙 영역의 실제 객체를 가리킨다.
기본 타입 8개를 제외하고 모든 객체, 배열등은 다 간접적으로 참조변수를 스택에 저장한다.
NullPointerException
ex) int[] intArray = null;
intArray[0] = 10; // 예외발생
String str = null;
System.out.println("총 문자수"+str.length()) // 예외발생
String name1 = '신용';
String name2 = '신용';
=> 힙 영역에 있는 동일한 객체 '신용'를 참조하는 형태(가리킴)
new 연산자를 이용한 String 객체 생성
String name1 = new String("신용권"); // 둘은 서로 다른 객체를 참조
String name2 = new String("신용권");
int Array1[];
String Array2[];
int[] Array1;
String[] Array2;
변수 = new 타입[] {값0, 값1, 값2, ..};
arr1 = new int[5];
하나의 배열을 다수의 레퍼런스가 참조 가능
참조변수는 곧 참조자이므로, 하나의 대상(배열 객체)을 여러개가 참조 가능
참조변수는 힙 영역의 위치한 배열 객체의 주소값을 저장(= 가리킴 = 참조함)
쉽게 생각해서, 한 객체가 여러 이름을 가진다 생각하면 됨.
ex) 어떤 사람(=객체) => 이욱, 자바 교수님 등의 이름(=참조변수)을 가질 수 있음
// 동일한 배열 객체 참조
int arr1[] = new int[5];
int arr2[] = arr1;
arr1[1] = 2;
arr2[1] = 6; // 2 에서 6으로 바뀜
배열은 객체이다
객체는 그 안에 여러 기능(메소드)과 값(field)을 가지고 있다
배열은 length 라는 필드를 가진다. (크기에 대한 정보가 담겨있다)
즉, 배열은 크기에 해당되는 변수, 그리고 값을 가지고있다.
배열 객체 참조변수를 통해 배열의 크기를 직접 받아올 수 있다
int[] scores = {1,2,3};
for(int i=0; i<scores.length; i++)
sum += scores[i];
2차원 배열 변수는 참조변수의 배열을 저장
물리적 형태
c++ 에서의 2차원배열은 그냥 쭉 그냥 늘여져있는 형태
자바에서는 각 1차원 배열을 가리키는 참조변수들이 있고, 그 참조변수들을 묶고 있는것이 2차원 배열 참조변수이다.
2차원 배열 생성시 행 단위의 배열로 쪼개고, 각 행의 배열 객체를 가리키고 있는 참조변수 배열을 만든다. 그리고 참조변수 배열을 2차원 배열 변수가 가리킨다.
int i[][];
i = new int[4][]; // 각 행을 가리키기 위한 참조변수 배열
// 행만 적어주고 열 값을 비워줌
// 계단식으로 각 행의 크기가 각각 1,2,3,4인 배열 생성
i[0] = new int[1];
i[1] = new int[2];
i[2] = new int[3];
i[3] = new int[4];