Languages/Java

[HUFS/객체지향프로그래밍] #4 참조 타입

성중 2022. 12. 27. 16:01

기본 타입과 참조 타입

  • 기본 타입(primitive type): 정수, 실수, 논리, 문자 리터럴 저장
  • 참조 타입(reference type): 배열, 열거, 클래스, 인터페이스 (객체의 번지를 참조)

 

기본 타입 변수와 참조 타입 변수의 차이점 (힙 영역 참조)

메모리 사용 영역

메모리 사용 영역(Runtime Data Area)은 메소드 / 힙 / JVM 스택 영역으로 나뉜다

  • 메소드 영역(Method Area): 클래스별로 정적 필드, 상수, 생성자, 메소드 등을 분류해 저장
  • 힙 영역(Heap Area): 객체와 배열이 생성되는 영역
  • JVM 스택 영역: 메소드가 호출되면 프레임이 추가되고 메소드가 종료되면 프레임이 제거

 

메모리 사용 영역
JVM 스택 영역
참조 타입의 ==, != 연산

null과 NullPointerException

참조 타입 변수는 객체를 참조하지 않는다는 뜻으로 null 값을 가질 수 있는데, 이 또한 스택 영역에 생성되며 null 상태의 변수를 사용할 경우 NullPointerException 오류(예외)가 발생한다

 

null
NullPointerException

String 타입

  • String 타입에 문자열을 대입할 경우 힙 영역에 String 객체가 생성되며 변수가 이를 참조
  • 문자열 리터럴이 동일한 경우 서로 다른 변수여도 같은 String 객체를 참조하는데, 이를 방지하려면 new 연산자로 새로운 String 객체를 생성
  • 이 때, == 연산자는 두 문자열이 같은 번지인지 (같은 객체를 참조하는지) 비교하고, 순수하게 문자열이 같은 지 비교하려면 equals()를 사용해야 함
  • String 변수에 null을 대입해 참조를 잃은 String 객체는 쓰레기 수집기(Garbage Collertor)에 의해 메모리에서 자동 제거

 

String 타입 비교 예시

package sec01.exam01;

public class StringEqualsExample {
	public static void main(String[] args) {	
		String strVar1 = "신민철";
		String strVar2 = "신민철";
		
		if(strVar1 == strVar2) {
			System.out.println("strVar1과 strVar2는 참조가 같음");
		} else {
			System.out.println("strVar1과 strVar2는 참조가 다름");
		}
		
		if(strVar1.equals(strVar2)) {
			System.out.println("strVar1과 strVar2는 문자열이  같음");
		}
		
		String strVar3 = new String("신민철");
		String strVar4 = new String("신민철");
				
		if(strVar3 == strVar4) {
			System.out.println("strVar3과 strVar4는 참조가 같음");
		} else {
			System.out.println("strVar3과 strVar4는 참조가 다름");
		}
		
		if(strVar3.equals(strVar4)) {
			System.out.println("strVar3과 strVar4는 문자열이  같음");
		}		
	} 
}

 

배열

데이터를 연속된 공간에 나열하고 각 데이터에 인덱스를 부여한 자료구조를 배열이라 하며, 같은 타입의 데이터만 저장할 수 있고 한 번 생성된 배열의 길이는 늘이거나 줄일 수 없다

 

배열
배열 변수 선언
배열 생성 (값 목록 or new 연산자)

배열 사용 예시

package sec02.exam01;

public class ArrayCreateByValueListExample1 {
	public static void main(String[] args) {
		int[] scores = { 83, 90, 87 };
		
		System.out.println("scores[0] : " + scores[0]);
		System.out.println("scores[1] : " + scores[1]);
		System.out.println("scores[2] : " + scores[2]);
		
		int sum = 0;
		for(int i=0; i<3; i++) {
			sum += scores[i];
		}
		System.out.println("총합 : " + sum);		
		double avg = (double) sum / 3;
		System.out.println("평균 : " + avg);
	}
}

 

length 필드: 배열에 저장할 수 있는 전체 요소 수 (변경 불가)

 main() 메소드의 String[] args 매개변수 또한 명령 라인들이 담긴 문자열 배열이다

 

명령 라인 입력
2차원 배열: 행렬 구조
2차원 배열: 계단식 구조
값 목록을 이용한 2차원 배열 생성
참조 타입 배열 (객체를 참조)

for문을 사용한 배열 복사

package sec02.exam08;

public class ArrayCopyByForExample {
	public static void main(String[] args) {
		int[] oldIntArray = { 1, 2, 3 };
		int[] newIntArray = new int[5];
		
		for(int i=0; i<oldIntArray.length; i++) {
			newIntArray[i] = oldIntArray[i];
		}
		
		for(int i=0; i<newIntArray.length; i++) {
			System.out.print(newIntArray[i] + ", ");
		}
	}
}

 

System.arraycopy()를 사용한 배열 복사

package sec02.exam09;

public class ArrayCopyExample {
	public static void main(String[] args) {
		String[] oldStrArray = { "java", "array", "copy" };
		String[] newStrArray = new String[5];
		
		System.arraycopy( oldStrArray, 0, newStrArray, 0, oldStrArray.length);
		
		for(int i=0; i<newStrArray.length; i++) {
			System.out.print(newStrArray[i] + ", ");
		}
	}
}

 

복사된 배열은 같은 객체 참조
배열이나 컬렉션을 순회하기 위해 향상된 for문

열거 타입

열거 상수(enum: 한정된 값)를 저장하는 열거 타입이 있다

 

열거 타입
열거 타입 선언
열거 타입 변수