JAVA/이론 정리 및 예제

[JAVA/자바] #4_1 배열 / 예제

chaewon 2021. 9. 5. 19:17

배열 (Array)

정리되지 않은 (동일한 자료형)변수들을 하나의 연속된 메모리 공간으로 묶음

배열은 저장된 값마다 인덱스 번호가 설정됨. (0부터 시작)

 

배열의 선언

// 배열의 사용 방법
// 배열의 선언
// 자료형[] 변수명;        -> 참조 변수 
// 자료형 변수명[]; 의 형식으로 선언할 수 있다.

// 선언은 stack에 배열의 주소를 보관할 수 있는 공간을 만드는 것이다.
	int[] iarr;
	char carr[];

 

배열의 할당

배열은 초기화X → 값을 대입한다.

// 선언한 레퍼런스변수에 배열을 할당하여 대입할 수 있다.
/*iarr = new int[];*/        // 크기를 지정해 주지 않아서 에러 발생
iarr = new int[5];
carr = new char[10];

// 선언과 할당을 동시에 할 수도 있다.
int[] iarr2 = new int[5];
char carr2[] = new char[10];

// 스캐너를 통해 입력받은 정수로 배열의 길이를 지정하여 배열을 할당할 수 있다.
Scanner sc = new Scanner(System.in);

System.out.print("새로 할당할 배열의 길이를 입력하세요 : ");
int size = sc.nextInt();

double[] darr = new double[size];

 

배열의 값 기록

  • heap에는 빈공간으로 할당할 수 없기 때문에 JVM이 지정한 초기값으로 배열이 초기화 된다.
  • 각 자료형의 초기값 
    • 정수형 - 0
    • 실수형 - 00
    • 문자형 - '\u0000'
    • 문자열 - null
    • boolean - false
	// 기본적으로 배열을 선언하고 할당을 하면 JVM이 지정한 값으로 배열이 초기화 된다.
	// heap영역은 값이 없는 공간이 존재할 수 없기 때문이다.
	int[] iarr = new int[5];            //{0, 0, 0, 0, 0}

	// JVM이 정한 기본값 외의 값으로 초기화를 하고 싶은 경우 블럭을 이용한다.
	// 블럭을 사용하는 경우 new를 사용하지 않아도 되며, 값의 갯수만큼 자동으로 크기가 설정된다.
	/*int[] iarr2 = {11, 22, 33, 44, 55};*/
	int[] iarr2 = new int[] {11, 22, 33, 44, 55};

	// 배열 이용
	int[] arr = new int[5];
	
	// 값을 대입할 때도 반복문을 사용할 수 있다.
	for(int i = 0, value = 0; i < arr.length; i++) {
			arr[i] = value += 10;
	}

 

 

배열의 저장 구조

  • int형 배열 5칸를 만들어 heap영역에 주소값(번지수)을 발생시키고
    stack에 int배열의 주소값을 가질 수 있는 iarr이라는 공간에 대입한다.
int[] iarr = new int[5];
stack heap static
int[]
[  0x1234 ]iarr
  (주소값)
0x1234
[  1  |  2  |  3  |  4  |  5  ]
   0     1     2      3     4     → 번지
 

주소값은 stack에서 heap을 참조한다.

new → 할당연산자 ( 주소값을 발생시켜라 )

 

.hashcode() 와 .length

// 해쉬코드는 실제 주소값이 아니고, 실제 주소를 찾기 위한 key역할을 한다.
// 자바에서는 직접적으로 하드웨어에 접근할 수 없기 때문에 정확한 메모리 주소를 알 수 없다. (jvm을 통해서 가능)
// 따라서 해쉬코드가 주소라고 생각할 순 없지만, 현재까지는 주소라고 생각해도 상관없\다.
System.out.println("iarr2의 hashcode : " + iarr2.hashCode());
System.out.println("carr2의 hashcode : " + carr2.hashCode());

// 처음 할당한 길이 추후에 size변경 불가 ->배열의 특징이자 단점
System.out.println("iarr2의 길이 : " + iarr2.length);
System.out.println("carr2의 길이 : " + carr2.length);

 

할당된 배열은 수정 불가

stack double[]
[              ]darr  
heap 0x1234    double[5]
[    |    |    |    |    ]


0x5678    double[30]
[  …..  ]


old영역 - GC가 삭제시킨다.

 

	double[] darr = new double[5];

	System.out.println("darr의 hashcode : " + darr.hashCode());
	System.out.println("darr의 길이 : " + darr.length);

	darr = new double[30];        //new라고 할때마다 새로운 배열 생성

	// 새로운 배열은 만든 후 레퍼런스 변수값(주소값)을 덮어쓴것
	// 다시 처음 배열을 찾아갈 수 없다.
	System.out.println("수정 후 darr의 hashcode : " + darr.hashCode());
	System.out.println("수정 후 darr의 길이 : " + darr.length);

	// 한번 할당된 배열은 지울 수 없다.
	// 다만 레퍼런스 변수를 null로 변경하여 더 이상 참조할 주소가 없게 된 배열은
	// 일정 시간이 지난 후 heap의 old영역으로 이동하여 GC(가비지 컬렉터)가 삭제
	// 그리고 다시는 이전에 참조하던 배열을 다시 참조할 수 없다.
	darr = null;         //참조를 끊는다.

	// NullPoninterException이 발생함
	// 아무것도 참조하지 않고 null이라는 특수한 값을 
	// 참조하고 있을 때 발생하는 에러
	// System.out.println("darr의 길이 : " + darr.length);                                   //에러 이 레퍼런스 변수는 null을 가리키고 있다.

	// 만약 NullPointerException을 방지하려면
	// if문으로 null check를 해 주어야 한다.
	if(darr != null) {
			System.out.println("삭제 후 darr의 길이 : " + darr.length);                             //죽은 코드이다.
	}